题目链接: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);
}