Description
众所周知,白神是具有神奇的能力的。
比如说,他对数学作业说一声“数”,数学作业就会出于畏惧而自己完成;对语文作业说一声“语”,语文作业就会出于畏惧而自己完成。
今天,语文老师和数学老师布置了许多作业,同学们纷纷寻找白神寻求帮助。白神作为一个助人为乐的人,便答应下来。
回到家,白神将这N份作业按顺序摊开,发现语文作业数学作业混在一起,这就让白神苦恼起来,他如果对连续一段作业喊出“数”,那么里面的语文作业就会由于过于慌乱而写满错解,不过如果白神再对其喊一声“语”,它又会写满正确答案。
虽然白神很强大,但是能力还是有限制的,一天只能使用K次,现在,白神想知道他能正确的完成多少份作业。
Input
第一行两个整数N,K。
第二行N个0或者1表示这份作业是语文作业还是数学作业。
Output
输出一个整数,表示白神能正确完成的作业数。
Sample Input
5 2
0 1 0 1 0
0 1 0 1 0
Sample Output
4
HINT
100%的数据中N ≤ 100000,K<=50.
Source
好骚的$dp$。首先如果说每个点只会被染一次色的话,我们是不是可以很轻松的推出$dp$转移式?事实上,发动$k$次技能,最多把序列分成$k*2-1$段,每段我们要数目较多的那种颜色,这样就可以转移了
代码:
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int n,K,ans,num; 5 int co[100010]; 6 int dp[100010][101][2]; 7 int main() 8 { 9 scanf("%d%d",&n,&K); 10 for(int i=1;i<=n;i++) scanf("%d",&co[i]),num+=co[i]==0; 11 for(int k=1;k<=2*K-1;k++) 12 for(int i=1;i<=n;i++) 13 for(int c=0;c<=1;c++) 14 { 15 dp[i][k][c]=max(dp[i-1][k-1][c^1],dp[i-1][k][c])+(c==co[i]); 16 ans=max(dp[i][k][c],ans); 17 } 18 printf("%d",ans); 19 return 0; 20 }