zoukankan      html  css  js  c++  java
  • 动态规划:HDU1160-FatMouse's Speed(记录动态规划状态转移过程)

    FatMouse's Speed

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 5546    Accepted Submission(s): 2393
    Special Judge


    Problem Description
    FatMouse believes that the fatter a mouse is, the faster it runs. To disprove this, you want to take the data on a collection of mice and put as large a subset of this data as possible into a sequence so that the weights are increasing, but the speeds are decreasing.


     

    Input
    Input contains data for a bunch of mice, one mouse per line, terminated by end of file.

    The data for a particular mouse will consist of a pair of integers: the first representing its size in grams and the second representing its speed in centimeters per second. Both integers are between 1 and 10000. The data in each test case will contain information for at most 1000 mice.

    Two mice may have the same weight, the same speed, or even the same weight and speed.


     

    Output
    Your program should output a sequence of lines of data; the first line should contain a number n; the remaining n lines should each contain a single positive integer (each one representing a mouse). If these n integers are m[1], m[2],..., m[n] then it must be the case that

    W[m[1]] < W[m[2]] < ... < W[m[n]]

    and

    S[m[1]] > S[m[2]] > ... > S[m[n]]

    In order for the answer to be correct, n should be as large as possible.
    All inequalities are strict: weights must be strictly increasing, and speeds must be strictly decreasing. There may be many correct outputs for a given input, your program only needs to find one.


     

    Sample Input
    6008 1300 6000 2100 500 2000 1000 4000 1100 3000 6000 2000 8000 1400 6000 1200 2000 1900


     

    Sample Output
    4 4 5 9 7
    题目链接:



    解题心得:
    1、这个题看似很复杂,其实只有几个环节处理好了之后就比较简单了。第一个环节是输入要求,是单组,但是是多组输入,输入到文件结束为止。处理完了输入要求之后是题目要求质量上升但是速度下降。可以按照质量升序排列一下,然后只剩下速度。然后找速度的最长下降子序列。最后还需要记录一下下降的子序列有哪些。
    2、最长下降子序列和最长上升子序列一样的,详情看点击打开链接(n^2算法),点击打开链接(nlogn算法)。主要是记录子序列中的元素有哪些。可以直接开一个dp的结构体,结构体中放一个数组,每次状态转移的时候可以将数组中的元素一起转移然后加上当前状态就可以了。
    3、这个问题告诉我们不要太过于死板了,状态转移,关于状态的定义不要过于死板了,只要可以跟着转移的都可以是状态,状态转移中可以有很多操作的。





    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1010;
    struct mice
    {
        int w,s;
        int pos;
    } m[maxn];
    
    struct Dp
    {
        int num[maxn];
        int Num;
    } dp[maxn];
    bool cmp(mice a,mice b)
    {
        return a.w<b.w;
    }
    int main()
    {
        int t = 1;
        int W,S;
        while(scanf("%d%d",&W,&S) != EOF)//处理这个题输入的的办法
        {
            m[t].w = W;
            m[t].s = S;
            m[t].pos = t;
            t++;
        }
        
        /*
        可以输入0 0结束看看自己的输入是否正确
        while(scanf("%d%d",&W,&S) && W)//处理这个题输入的的办法
        {
            m[t].w = W;
            m[t].s = S;
            m[t].pos = t;
            t++;
        }
        t--;
        for(int i=1;i<=t;i++)
            printf("%d %d
    ",m[i].w,m[i].s);
            
        */
        
        t--;//用来记录有多少个元素
        int Max = 0;//记录最长的递减子序列
        sort(m,m+t,cmp);//拍一下序,cmp函数自己写一下
        for(int i=1;i<=t;i++)
        {
            dp[i].Num = 1;
            dp[i].num[1] = m[i].pos;
        }
        for(int i=1; i<=t; i++)
        {
            for(int j=0; j<=i; j++)
            {
                if(m[j].s > m[i].s && m[j].w < m[i].w)
                {
                    if(dp[j].Num+1 > dp[i].Num)//如果符合状态的转移要求
                    {
                        for(int k=1;k<=dp[j].Num;k++)//记录状态的数组一起跟着转移
                        {
                            dp[i].num[k] = dp[j].num[k];
                            dp[i].num[k+1] = m[i].pos;//当前状态也要放入
                        }
                        dp[i].Num = dp[j].Num + 1;
                        if(dp[i].Num > Max)
                            Max = dp[i].Num;
                    }
                }
            }
        }
    
        bool flag = false;
        printf("%d
    ",Max);
        for(int i=1;i<=t;i++)
        {
            if(dp[i].Num == Max)
            {
                flag = true;
                for(int j=1;j<=dp[i].Num;j++)
                {
                    if(dp[i].num[j]!=0)
                    printf("%d
    ",dp[i].num[j]);
                }
                break;
            }
        }
        return 0;
    }
    


  • 相关阅读:
    python学习之路——匿名行数/函数递归与二分法
    python学习之路——作业 day16(18/10/10)
    python学习之路——global与nonlocal.py、装饰器
    python学习之路——命名关键字参数、函数对象、函数嵌套、名称空间与作用域、闭包函数
    matplotlib绘图库
    Java快速入门
    Eclipse常用快捷键
    Python网络爬虫-Scrapy框架
    Python网络爬虫-requests模块(II)
    Python网络爬虫-requests模块
  • 原文地址:https://www.cnblogs.com/GoldenFingers/p/9107344.html
Copyright © 2011-2022 走看看