题意:
要找出老鼠体重递减,速度递增的最长序列。输出这个最长序列max的值和其max个结点。
分析:
hdu dp之二:
贴下分析:
设Mice[i].W表示第i只老鼠的重量,Mice[i].S表示第i只老鼠的速度。我们先对Mice进行排序,以W为第一关键字,从小到大,S为第二关键字,从大到小。
设f[i]为Mice[i]至Mice[n]最长的序列长度。考虑某一个f[i],则有:
f[i] = max(f[i], f[j]+1) (1<=j<i,且Mice[i].W> Mice[j].W,Mice[i].S < Mice[j].S)
其中,初始条件为f[i]=1 (i=1, 2, ..., n)。
自己卡这题有些时间(感谢芒果...>_<),问题出在len上从0输到len,上届应该是i<len而不是len-1,凌乱了,只能怪自己做题时不小心。
一开始把序列输出来了,但不知道应该怎么选,就随便选了,结果当然是wa,后来,经提醒增设个数组pre[]保存其父节点,这样找到其最大结点时就可以根据父节点
找回来。
还有一个问题是自己本来是从i出发然后去找i以后的发现这样不行,然后又改成找i之前的才行....>_<
#include <iostream> #include <cstdio> #include <stdlib.h> using namespace std; typedef struct mice { int w,s,n; }mice; int cmp(const void *a , const void *b ) { mice *c = (mice *)a; mice *d = (mice *)b; if(c->w!= d->w) return c->w - d->w; else return d->s-c->s; } int main() { mice M[10005]; int len=0,i,j,F[10005],pre[10005]; M[len].n=1; pre[0]=0; int max=1,flag=1; while(~scanf("%d%d",&M[len].w,&M[len].s)) { len++; M[len].n=M[len-1].n+1; } // for(i=0;i<len-1;i++) // cout<<M[i].n<<endl; //cout<<endl; qsort(M,len,sizeof(M[0]),cmp); // for(i=0;i<len-1;i++) // cout<<M[i].w<<" "<<M[i].s<<" "<<M[i].n <<endl; for(i=0;i<len;i++) F[i]=1; for(i=1;i<len;i++) { for(j=i-1;j>=0;j--) { if(M[i].w>M[j].w&&M[i].s<M[j].s&&F[i]<(F[j]+1)) { F[i]=F[j]+1; pre[i]=j; } } if(max<F[i])//记录取到的最长序列 { max=F[i]; flag=i; } } //for(i=0;i<len-1;i++) //cout<<F[i]<<endl; // cout<<endl; j=max-1; for(i=0;i<max;i++) { F[j--]=flag; flag=pre[flag]; } cout<<max<<endl; for(i=0;i<max;i++) cout<<M[F[i]].n<<endl; return 0; }
明天就要考英语了,关键是后天要校赛了,昨天晚上想了很久,感觉失眠一般,上次校赛带给我的阴影太大了而且这次的身份又不一样,好痛苦。
还是尽力去做吧。enjoy it!