完美队形(区间dp)

来源:互联网 发布:csgo mac版 编辑:程序博客网 时间:2024/05/20 18:41

前言:感觉这是道神题,某神犇的代码只有300b+


这题最难点在于状态的定义
可以很清楚地知道这应该是大区间转小区间
或者说是在一个范围内转移状态
但这个范围有不能枚举
而这题的正解优越性在于使用线性的遍历保证了区间的范围,使状态可以轻松地转移


重点看for的顺序:

#include<cstdio>#define FOR(i,x,y) for(int i=(x);i<=(y);i++)#define DOR(i,x,y) for(int i=(x);i>=(y);i--)int A[505];int dp[505];//右半边最左边的人==右半边最高的人 int main(){    int n;    scanf("%d",&n);    FOR(i,1,n)scanf("%d",&A[i]);    int ans=0;    FOR(i,1,n){//枚举的i一定在dp[j]所对应的范围内        int mx=0;        DOR(j,n,i){            if(A[i]>A[j]&&dp[j]>mx)mx=dp[j];            else if(A[i]==A[j]){                if(i!=j&&dp[j]<mx+2)dp[j]=mx+2;                else if(i==j&&dp[j]<mx+1)dp[j]=mx+1;            }        }    }    FOR(i,1,n)if(ans<dp[i])ans=dp[i];    printf("%d\n",ans);    return 0;}