• ZOJ 1108 FatMouse's Speed 动态规划


    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=108

    题目大意:证明老鼠重量越重,速度越慢,给你一组老鼠的数据(包括重量和速度),要求输出满足前面条件的最长的子序列的老鼠编号

    首先,按照老鼠的重量进行升序和速度的降序排列;

    然后,根据动态方程求解

    len[0]=1;len[i]=max{len[j]}+1 (0<=j<i)

    最后,输出老鼠的编号顺序,为了能够输出顺序的编号,所以要给老鼠一个index和preIndex,最后输出时最好的方法是采用递归的方式

    注意:

    1.题目的结束是以文件结尾为结束符,在C和C++中是 EOF,但是在Java里文件结束是null,用Scanner和 BufferedReader 都可以,接着判断
    (str = br.readLine()).equals("")就可以了;
    或者是 !(str = sin.nextLine()).equals("")
    2.使用BufferedReader每次读取的都是一行数据,这里我要得到的是以空格隔开来的两个数字,可以使用StringTokenizer,也可以使用Scanner,当然
    这道题目其实使用String的各种操作也是可以实现的。

      

    int w2=Integer.parseInt(str.substring(0, str.indexOf(" ")));//区别在这里

      int s2=Integer.parseInt(str.substring(str.indexOf(" ")+1));

    我的Java代码:【注意:结果是TLE,我实在是没有办法】

    /**
    * 修改排序方法,使用Collections.sort
    * 修改设置preIndex的方法和输出方式
    * 结果:TLE
    */
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.Scanner;

    public class ZOJ1108_4 {

    public static int n;// 记录老鼠的数目
    public static int[] len;// 记录以原序列中第i个老鼠结尾的最长的子序列
    public static int maxlen, maxIndex;// 分别表示最大长度和最后的老鼠的index
    public static ArrayList<Mouse> mice = new ArrayList<Mouse>();// 记住要new,不然会报空指针

    public static void main(String[] args) throws Exception {
    BufferedReader br
    = new BufferedReader(new InputStreamReader(System.in));
    n
    = 0;
    String str;
    while (!(str = br.readLine()).equals("")) {
    Scanner sin
    = new Scanner(str);
    int w = sin.nextInt();
    int s = sin.nextInt();
    Mouse m
    = new Mouse(n + 1, w, s);
    n
    ++;
    mice.add(m);
    }
    Collections.sort(mice,
    new Comparator<Mouse>() {
    public int compare(Mouse o1, Mouse o2) {
    if (o1.weight > o2.weight) {
    return 1;
    }
    else if (o1.weight == o2.weight && o1.speed < o2.speed) {
    return 1;
    }
    else {
    return -1;
    }
    }
    });
    dpSpeed();
    System.out.println(maxlen);
    output(maxIndex);
    }

    //根据老鼠的速度进行dp
    private static void dpSpeed() {
    len
    = new int[n];
    int i, j, k;
    maxlen
    = 0;
    maxIndex
    = 0;
    len[
    0] = 1;
    mice.get(
    0).preIndex = 0;
    for (i = 1; i < n; i++) {
    len[i]
    = 1;
    for (j = 0; j < i; j++) {
    if (mice.get(i).speed < mice.get(j).speed
    && mice.get(i).weight > mice.get(j).weight) {
    if (len[j] >= len[i]) {// 注意这里可以等于,也许刚好满足条件的那个就是长度为1[可以调试]
    len[i] = len[j] + 1;
    mice.get(i).preIndex
    = j;
    }
    }
    }
    }
    for (k = 0; k < n; k++) {
    if (len[k] > maxlen) {
    maxlen
    = len[k];
    maxIndex
    = k;
    }
    }
    }

    //用递归的方式输出
    private static void output(int index) {
    if(len[index]==1){
    System.out.println(mice.get(index).index);
    }
    else{
    output(mice.get(index).preIndex);
    System.out.println(mice.get(index).index);
    }
    }
    }

    class Mouse {
    int index;// 记录该老鼠是原序列的第几位
    int weight;// 记录重量和速度
    int speed;
    int preIndex;// 记录该老鼠在得到的序列中的上一个老鼠的index

    public Mouse() {

    }

    public Mouse(int index, int weight, int speed) {
    this.index = index;
    this.weight = weight;
    this.speed = speed;
    }
    }

    换了一种方式,结果是RE,不知道哪里出错了

    /**
    * 修改排序方法,使用Collections.sort
    * 修改设置preIndex的方法和输出方式
    * 修改了得到输入数据的方法
    * 结果:RE
    */
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.Scanner;

    public class Main{

    public static int n;// 记录老鼠的数目
    public static int[] len;// 记录以原序列中第i个老鼠结尾的最长的子序列的长度
    public static int maxlen, maxIndex;// 分别表示最大长度和最后的老鼠的index
    public static ArrayList<Mouse> mice = new ArrayList<Mouse>();// 记住要new,不然会报空指针

    public static void main(String[] args){
    Scanner sin
    =new Scanner(System.in);
    n
    = 0;
    String str;
    while (!(str = sin.nextLine()).equals("")) {//利用nextLine方法也是可以的!
    int w2=Integer.parseInt(str.substring(0, str.indexOf(" ")));//区别在这里
    int s2=Integer.parseInt(str.substring(str.indexOf(" ")+1));
    Mouse m
    = new Mouse(n + 1, w2, s2);
    n
    ++;
    mice.add(m);
    }
    Collections.sort(mice,
    new Comparator<Mouse>() {
    public int compare(Mouse o1, Mouse o2) {
    if (o1.weight > o2.weight) {
    return 1;
    }
    else if (o1.weight == o2.weight && o1.speed < o2.speed) {
    return 1;
    }
    else {
    return -1;
    }
    }
    });
    dpSpeed();
    System.out.println(maxlen);
    output(maxIndex);
    }

    //根据老鼠的速度进行dp
    private static void dpSpeed() {
    len
    = new int[n];
    int i, j, k;
    maxlen
    = 0;
    maxIndex
    = 0;
    len[
    0] = 1;
    mice.get(
    0).preIndex = 0;
    for (i = 1; i < n; i++) {
    len[i]
    = 1;
    mice.get(i).preIndex
    =i;
    for (j = 0; j < i; j++) {
    if (mice.get(i).speed < mice.get(j).speed
    && mice.get(i).weight > mice.get(j).weight) {
    if (len[j] >= len[i]) {// 注意这里可以等于,也许刚好满足条件的那个就是长度为1[可以调试]
    len[i] = len[j] + 1;
    mice.get(i).preIndex
    = j;
    }
    }
    }
    }
    for (k = 0; k < n; k++) {
    if (len[k] > maxlen) {
    maxlen
    = len[k];
    maxIndex
    = k;
    }
    }
    }

    //用递归的方式输出
    private static void output(int index) {
    if(len[index]==1){//巧妙之处:最后的那个的len[]==1
    System.out.println(mice.get(index).index);
    }
    else{
    output(mice.get(index).preIndex);
    System.out.println(mice.get(index).index);
    }
    }
    }

    class Mouse {
    int index;// 记录该老鼠是原序列的第几位
    int weight;// 记录重量和速度
    int speed;
    int preIndex;// 记录该老鼠在得到的序列中的上一个老鼠的index

    public Mouse() {

    }

    public Mouse(int index, int weight, int speed) {
    this.index = index;
    this.weight = weight;
    this.speed = speed;
    }
    }

      

    解题时我参考了网上一位同学的方法,很是不错啊,和我的差不多,不过输出我是参考他的

    他用的是C++,顺利 AC ,我们的算法时间复杂度都是 O(n^2)。。。【详情可见我的博客中的另外一篇博文】

    虽说还有一种更好的算法 O(nlog(n)),但是我怎么都没写出来,因为那个比较的方式太复杂了点

    #include <iostream>
    #include
    <algorithm>
    #define MAX 1005
    using namespace std;

    struct Mice
    {
    int id;
    int weight;
    int speed;
    int pre;
    };


    bool cmp(const Mice& a, const Mice& b)
    {
    if (a.weight < b.weight)
    return true;
    else if (a.weight == b.weight)
    return a.speed > b.speed;
    else
    return false;
    }

    int num[MAX];
    Mice mice[MAX];

    void output(int);

    int main()
    {
    int count = 0;

    while (cin >> mice[count].weight >> mice[count].speed)
    {
    mice[count].id
    = count+1;
    count
    ++;
    }


    sort(mice, mice
    +count, cmp);

    num[
    0] = 1;
    mice[
    0].pre = 0;

    for (int i = 1; i < count; i++)
    {
    num[i]
    = 1;
    mice[i].pre
    = i;

    for (int j = 0; j < i; j++)
    {
    if (mice[i].weight > mice[j].weight && mice[i].speed < mice[j].speed)
    {
    if (num[i] < num[j]+1)
    {
    num[i]
    = num[j]+1;
    mice[i].pre
    = j;
    }
    }
    }

    }

    int max_index = 0;
    for (int i = 1; i < count; i++)
    if (num[i] > num[max_index])
    max_index
    = i;

    cout
    << num[max_index] << endl;

    output(max_index);
    return 0;
    }


    void output(int index)
    {
    if (num[index] == 1)
    cout
    << mice[index].id << endl;
    else
    {
    output(mice[index].pre);
    cout
    << mice[index].id << endl;
    }
    }

      

  • 相关阅读:
    浮动 float
    display属性和特性
    盒子阴影
    内边距
    外边距
    边框
    网页背景
    猴子补丁
    设计模式创造者模式--python
    Go语言:validator库对请求参数校验
  • 原文地址:https://www.cnblogs.com/yinger/p/2113235.html
Copyright © 2020-2023  润新知