zhber
有好多做过的题没写下来,如果我还能记得就补吧

Description

众所周知,白神是具有神奇的能力的。

比如说,他对数学作业说一声“数”,数学作业就会出于畏惧而自己完成;对语文作业说一声“语”,语文作业就会出于畏惧而自己完成。

今天,语文老师和数学老师布置了许多作业,同学们纷纷寻找白神寻求帮助。白神作为一个助人为乐的人,便答应下来。

回到家,白神将这N份作业按顺序摊开,发现语文作业数学作业混在一起,这就让白神苦恼起来,他如果对连续一段作业喊出“数”,那么里面的语文作业就会由于过于慌乱而写满错解,不过如果白神再对其喊一声“语”,它又会写满正确答案。

虽然白神很强大,但是能力还是有限制的,一天只能使用K次,现在,白神想知道他能正确的完成多少份作业。

Input

第一行两个整数N,K。
第二行N个0或者1表示这份作业是语文作业还是数学作业。

Output

输出一个整数,表示白神能正确完成的作业数。

Sample Input

5 2
0 1 0 1 0

Sample Output

4


HINT

 

100%的数据中N ≤ 100000,K<=50.

 
因为是覆盖k段,最多可以有2k-1段01相间的区间
然后f[i][j][0/1]表示前i个涂j段,并且最后一段是0/1的方案数
#include<cstdio>
#include<iostream>
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int a[100010];
int f[100010][100][2];
int n,m;
int main()
{
    n=read();m=2*read()-1;
    for (int i=1;i<=n;i++)a[i]=read();
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
        {
            f[i][j][0]=max(f[i-1][j][0],f[i-1][j-1][1])+(a[i]==0);
            f[i][j][1]=max(f[i-1][j][1],f[i-1][j-1][0])+(a[i]==1);
        }
    printf("%d\n",max(f[n][m][0],f[n][m][1]));
    return 0;
}

 

posted on 2014-12-23 11:22  zhber  阅读(257)  评论(0编辑  收藏  举报