#include <iostream> #include <algorithm> /* ashione 2011-6-15 DP 类似于最长递增子序列,只不过最重要的就是保存路径 由题意可以得出,作为自身就是一个序列(长度为1的), 那么我们下面定义的就是 f[1...n]=1 说的就是这个; 这个用fill_n()函数来初始化它,注:memset()是按位初始化。 max 表示它的最长序列,p指向它最长序列的最后一个元素,最后方便递归调用, 结构的中的 w,s 为数据,loca 为原始数据位置,pre 为子序列中前一个的下标。 状态转移方程为 f[i]=max( f[i], max(f[1...i-1])+1 ) 当其形成序列的时候,也就是满足序列条件的时候。 */ using namespace std; typedef struct{ int w,s,loca,pre; }fat; #define M 1005 fat maze[M+1]; bool cmp(const fat a,const fat b){ //按关键字分别排序 if(a.w!=b.w) return a.w<b.w; return a.s>b.s; } void output(int n,int p){ //输出最后的路径,类似与BFS输出 if(n==1) cout<<maze[p].loca<<endl; else output(n-1,maze[p].pre),cout<<maze[p].loca<<endl; } void slove(int n){ int i,j,f[M]; int max=0,p=0; fill_n(f,n+1,1); //可以知道,每一个自身都可以算作是一个序列 for(i=0;i<n;i++){ for(j=0;j<i;j++){ if( f[i]<f[j]+1 && maze[i].w>maze[j].w && maze[i].s<maze[j].s){ f[i]=f[j]+1; maze[i].pre=j; if(max<f[i]) max=f[i],p=i; } } } cout<<max<<endl; output(max,p); } int main(){ int i=0; while(scanf("%d %d",&maze[i].w,&maze[i].s)!=EOF) maze[i].loca=i+1,i++; int n=i; sort(maze,maze+n,cmp); slove(n); return 0; }