bzoj3791: 作业

3791: 作业

链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3791

Time Limit: 10 Sec  Memory Limit: 256 MB

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.

题解:dp, 相当于

给一个长度为 N 的序列,序列中每个元素初始为无色,每个元素有一个目标颜色(黑或白),你有 K 次机会选择一个区间染色,注意颜色会覆盖。问最多能让多少个元素满足目标颜色。
 
注意染到最后一定是黑白相间的。而最多形成 2*k-1 个黑白相间的段,并且个数小于 2*k-1 的黑白相间的段都能被染出。
 
dp[i][j][0/1] 表示染到第 i 个,已经有了 j 段,最后一段是      白/黑色,最多的满足目标颜色的元素个数。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int M = 100005;
int dp[M][105][2], a[M];
int main()
{
     
    int n, k, ans = 0;
    scanf("%d%d", &n, &k);
    int tot = k * 2 - 1;
    for(int i = 1; i <= n; i++)scanf("%d", &a[i]);
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= tot; j++){
            dp[i][j][0] = max(dp[i - 1][j][0], dp[i - 1][j - 1][1]);
            dp[i][j][1] = max(dp[i - 1][j][1], dp[i - 1][j - 1][0]);
            if(a[i])dp[i][j][1]++;
            else dp[i][j][0]++;
        }
    /*for(int i = 1; i <= tot; i++)
        ans = max(dp[n][i][0], max(ans, dp[n][i][1]));*/
    printf("%d", max(dp[n][tot][1], dp[n][tot][0]));
    return 0;
}
View Code

 

posted @ 2018-08-11 18:18  Ed_Sheeran  阅读(166)  评论(0编辑  收藏  举报