Description

有两棵APP树,编号为1,2.每一秒,这两棵APP树中的其中一棵会掉一个APP.每一秒,你可以选择在当前APP树下接APP,或者迅速移动到另外一棵APP树下接APP(移动时间可以忽略不计),但由于却乏锻炼,你最多移动W次.问在T秒内,你最多能收集多少个APP.假设你开始站在1号APP树下.

Input

第1行:两个整数T(1 < = T< = 1000)和W(1 < = W< = 30)
第2..T+1行:1或2,代表每分钟掉落APP的那棵树的编号

Output

一行一个整数,代表你移动不超过W次能接住的最大APP数

Sample Input

7 2
2
1
1
2
2
1
1

Sample Output

6

题意上写了一开始在第一颗树下,要不然就得再加一个状态了

把i定义为时间,j定义为来回的步数

dp[i][j]=max(dp[i-1][j-1],dp[i-1][j])+如果在树下+1,不在树下+0;

然后根据第一个苹果初始化一下dp[1][1],dp[1][0];

剩下的就是如果当前时间当前位置在不在树下了

#include <iostream>
#include <stdio.h>
#include <cstring>
#define maxn 1000+5
using namespace std;
int a[maxn],dp[maxn][maxn];
int main()
{
    int t,w;
    while(scanf("%d%d",&t,&w)!=EOF){
        for(int i=1;i<=t;i++)scanf("%d",&a[i]);
        if(a[1]&1)dp[1][0]=1,dp[1][1]=0;
        else dp[1][0]=0,dp[1][1]=1;
        int ans=0;
        for(int i=2;i<=t;i++){
            for(int j=0;j<=w;j++){
                if(!j){
                    dp[i][j]=dp[i-1][j]+a[i]%2;
                }
                dp[i][j]=max(dp[i-1][j-1],dp[i-1][j]);
                if (j % 2 + 1 == a[i]){
					dp[i][j] ++;
				}
				ans=max(dp[i][j],ans);

            }
        }
        printf("%d\n",ans);
    }
    return 0;
}