1045 Favorite Color Stripe (30分)

这个题很明显是道DP题,因为这题看着很明显是动态的。
看下数据范围,喜欢的颜色是200,条带长度是10000,那么就是2e6,空间就确定了,状态方程就很容易确定。
定义dp[i][j]为当下标为i时,挑选的上一个喜欢的颜色为j时的最大长度。
那么dp方程就很好确定了。
如果下标为i的颜色时喜欢的颜色,那么,dp[i][j]=max(dp[i-1][k],dp[i][j]); k是允许放在j左边的颜色,包括颜色i。
如果不是就,复制上一层的状态给当前i就可以了。

#include <bits/stdc++.h>
using namespace std;

int a[10009],dp[10009][209];
int vis[209],b[209],le[209][209];

int main() {
#ifdef ONLINE_JUDGE
#else
    freopen("in.txt","r",stdin);
#endif

    int N,M,L;
    scanf("%d",&N);
    scanf("%d",&M);
    for (int i=1;i<=M;i++) {
        scanf("%d",&b[i]);
        vis[b[i]]=1;
        for (int j=1;j<=i;j++) {
            le[b[i]][b[j]]=1;
        }
    }
    scanf("%d",&L);
    for (int i=1;i<=L;i++) {
        scanf("%d",&a[i]);
        if (vis[a[i]]) {
            int mx=0;
            for (int j=1;j<=M;j++) {
                int k=b[j];
                dp[i][k]=dp[i-1][k];
                if (le[a[i]][k]) mx=max(mx,dp[i-1][k]);
            }
            dp[i][a[i]]=mx+1;
        } else {
            for (int j=1;j<=M;j++) {
                int k=b[j];
                dp[i][k]=dp[i-1][k];
            }
        }
        // for (int j=1;j<=M;j++) {
        //     int k=b[j];
        //     printf("%d ",dp[i][k]);
        // }
        // putchar('\n');
    }
    int ans=0;
    for (int i=1;i<=M;i++) ans=max(ans,dp[L][b[i]]);
    printf("%d\n",ans);
    return 0;
}
posted @ 2020-05-31 21:44  xyee  阅读(172)  评论(0编辑  收藏  举报