[HDU 1160 ] FatMouse's Speed [LIS 原理+ 路径输出]

来源:互联网 发布:ubuntu win7双系统 编辑:程序博客网 时间:2024/06/04 18:23

很多肥老鼠认为,长的越肥,奔跑速度就越快,为了反驳这个观点,你现在需要对老鼠的体重和速度进行研究,你要在老鼠序列中找出一个子序列,使得老鼠的体重在增加,但是速度却在减慢
Input
输入以eof结束。
输入中每行有两个正整数,分别表示老鼠的体重和速度,范围均在1到10000之间,输入数据最多有1000只老鼠。
某些老鼠可能有相同的体重,某些老鼠可能有相同的速度,某些老鼠可能体重和速度都相同。
Output

我们是要在原来的老鼠序列中,找到一个最长的子序列,使得这个子序列中老鼠的体重在严格增加,速度却在严格降低。
首先输出满足条件的最长的子序列的长度。
其次,输出一个最长子序列的方案,要求输出每个老鼠在输入时候的编号,每个编号占一行,任意一种正确的方法都会被判正确。
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

终于有道不看题解能够写出来的dp啦。
分析一下吧,其实我觉得这个就是和LIS的原理一样[o(n^2)的那个原理很像] 不过是另外加啦一个条件罢啦,我们可以按照体重的从小到大排,体重如果一样就按照速度减小来排。 然后我们设置dp[i] 表示以当前的i老鼠为最后一个的最长的上升子序列的长度。状态转移方程
dp[i]=1;
dp[i]=max(dp[i],dp[j]+1) ; 。 路径输出的话,我们可以用用一个数组来记录前驱 ,然后递归打印就好。
代码

 #include<bits/stdc++.h>using namespace std;typedef long long LL;const int inf =0x3f3f3f3f;const int MAXN = 1000+100;struct Mas{    int id,wight,speed;}mas[MAXN];bool cmp(Mas a,Mas b){    if(a.wight==b.wight) return a.speed>b.speed;    return a.wight<b.wight;}int pre[MAXN];int dp[MAXN];void print(int pos){    if(pos!=pre[pos]) print(pre[pos]);    printf("%d\n",mas[pos].id);}int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int size=0;    int a,b;    while(scanf("%d %d",&a,&b)!=EOF){         mas[size].id=size+1;         mas[size].wight=a;         mas[size++].speed=b;    }     sort(mas,mas+size,cmp);    /*for(int i=0;i<size;i++){        printf("wight =%d  speed =%d\n",mas[i].wight,mas[i].speed);    }*/// LIS原理的记录路径int ans=-1;int pos=-1;    for(int i=0;i<size;i++){            dp[i]=1;pre[i]=i; // 什么都不跟,长度为1        for(int j=0;j<i;j++){            if(mas[i].wight>mas[j].wight&&mas[i].speed<mas[j].speed) {//就是这里添加啦另一个条件和LIS的不同                if(dp[i]<dp[j]+1) {                     pre[i]=j;                               dp[i]=dp[j]+1;                }                //dp[i]=max(dp[i],dp[j]+1);             }            if(ans<dp[i]) {                pos=i;//记录最长的子序列的尾端序号。                ans=dp[i];            }            //ans=max(ans,dp[i]);        }    }    printf("%d\n",ans);    print(pos);    return 0;}

我是先把求长度的代码写出来,然后再那个基础上想下在哪里添加可以以记录前驱,感觉这样好点。