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;
    }
    


  • 相关阅读:
    iOS开发笔记18:一些编译、开发调试、打包的细节整理
    iOS开发笔记17:自定义相机拍照
    iOS开发笔记15:地图坐标转换那些事、block引用循环/weak–strong dance、UICollectionviewLayout及瀑布流、图层混合
    iOS开发笔记14:微博/微信登录与分享、微信/支付宝支付
    iOS开发笔记13:顶部标签式导航栏及下拉分类菜单
    iOS开发笔记12:iOS7上UITextField限制字数输入导致崩溃问题
    iOS开发笔记11:表单键盘遮挡、浮点数价格格式化显示、省市区选择器、View Debugging
    iOS开发笔记10:圆点缩放动画、强制更新、远程推送加语音提醒及UIView截屏
    iOS开发笔记9:NSUserDefaults存储自定义实体对象
    iOS开发笔记8:Remote Notification远程消息推送处理
  • 原文地址:https://www.cnblogs.com/GoldenFingers/p/9107344.html
Copyright © 2011-2022 走看看