HDU 1160 FatMouse's Speed (LIS +路径标记)

思路:要求最长的序列肯定是LIS,并且路径也要标记下来。这里的路径标记和做AOE网络上标记路径类似都是通过在状态转化时,进行pre[i]=j;i的前边是j(下标)。然后通过一个循环将顺序转换过来,但是注意判断终止的条件,是i=pre[i],之后判断i是不是0。(同时这题的输入也很坑)。


#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<queue>
#include<map>
#include<stack>
#define L1 long long
#define L2 int
#define inf 0x3f3f3f3f
using namespace std;
const int m1=1001000;
const int m2=1010;
int dp[10005];
struct node
{
    int w,s,id;
//    bool operator<(const node&p)const
//    {
//        if(w==p.w)
//            return s<p.s;
//        return w<p.w;
//    }
}q[1000010];
int pre[1000010];
int cmp(node a,node b){
    if(a.w==b.w){
        return a.s<b.s;
    }
    return a.w<b.w;
}
int main()
{
    int n,m,i,j,k,cnt=1;
    while(~scanf("%d%d",&q[cnt].w,&q[cnt].s)){
        q[cnt].id=cnt;
        cnt++;
    }
    cnt-=1;
    sort(q+1,q+cnt+1,cmp);
    memset(pre,0,sizeof(pre));
    for(i=0;i<=cnt;i++){
        dp[i]=1;
    }

    int ma=0,bj=1;
    for(i=1;i<=cnt;i++){
        for(j=1;j<=i;j++){
            if(q[j].s>q[i].s&&q[j].w<q[i].w&&dp[i]<dp[j]+1){
                dp[i]=dp[j]+1;
                pre[i]=j;
                if(dp[i]>ma){
                    ma=dp[i];
                    bj=i;
                }
            }
        }
    }
    //printf("%d\n",bj);
    int t=0;
    for(int i=bj;i!=0;i=pre[i]){
        dp[t++]=i;
    }

    printf("%d\n",ma);
    for(i=t-1;i>=0;i--){
        printf("%d\n",q[dp[i] ].id);
    }
    return 0;
}


你可能感兴趣的:(dp)