Bzoj3791:作业:DP

来源:互联网 发布:数据库市场占有率 2016 编辑:程序博客网 时间:2024/06/05 04:14

题目链接:3791:作业

一段序列用K种不同的颜色染色最多染成2*K-1段

然会就可以考虑dp了

设dp[i][j][k]表示染到了第i个作业,共染了j段,当前染的颜色为k(k为0/1)

如果当前颜色和上一段一样,dp[i][j][k]=max(dp[i][j][k],dp[i-1][j][k]+(a[i]==k));

否则如果染得不一样,也就是多染了一段,dp[i][j][k]=max(dp[i][j][k],dp[i-1][j-1][k^1]+(a[i]==k));

i这一维用滚动数组滚一下即可

#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int maxn=500010;int n,K,dp[2][100][2],a[maxn],ans=0;int main(){scanf("%d%d",&n,&K);for (int i=1;i<=n;++i) scanf("%d",&a[i]);dp[1][1][a[1]]=1; int cur=1;for (int i=2;i<=n;++i){cur^=1;     for (int j=1;j<=K*2-1;++j)        for (int k=0;k<2;++k){            dp[cur][j][k]=max(dp[cur][j][k],dp[cur^1][j][k]+(a[i]==k)),            dp[cur][j][k]=max(dp[cur][j][k],dp[cur^1][j-1][k^1]+(a[i]==k)),ans=max(ans,dp[cur][j][k]);}}printf("%d",ans);}


4 0