HDU-6376 度度熊剪纸条

版权声明:选经典题目,写精品文章. https://blog.csdn.net/nka_kun/article/details/81605642

                                                                          度度熊剪纸条

                                                 Time Limit: 2000/1000 MS (Java/Others)


Problem Description
度度熊有一张纸条和一把剪刀。

纸条上依次写着 N 个数字,数字只可能是 0 或者 1。

度度熊想在纸条上剪 K 刀(每一刀只能剪在数字和数字之间),这样就形成了 K+1 段。

他再把这 K+1 段按一定的顺序重新拼起来。

不同的剪和接的方案,可能会得到不同的结果。

度度熊好奇的是,前缀 1 的数量最多能是多少。
 

Input
有多组数据,读到EOF结束。

对于每一组数据,第一行读入两个数 N 和 K 。

第二行有一个长度为 N 的字符串,依次表示初始时纸条上的 N 个数。

0≤K<N≤10000

所有数据 N 的总和不超过100000
 

Output
对于每一组数据,输出一个数,表示可能的最大前缀 1 的数量。
 

Sample Input
5 1
11010
5 2
11010
 

Sample Output
2
3
 

思路:判断各种细节忒麻烦了,还是01背包搞一搞吧......

代码:

#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 2e5+5;

int n,m;
int w[maxn],v[maxn],dp[maxn];
char s[maxn];

int main()
{
	while(cin>>n>>m)
	{
		mem(dp,0);
		mem(w,0);
		scanf(" %s",s);
		n = strlen(s);
		
		int cnt = 0;
		for(int i = 0;i< n;i++)
		{
			if(s[i] == '1')
			{
				cnt++;
				while(s[i] == '1'&&i< n) i++,w[cnt]++;
			}
		}
		
		for(int i = 1;i<= cnt;i++) v[i] = 2;
		if(s[0] == '1') v[1] = 1;
		if(s[n-1] == '1') v[cnt] = 1;
		m++;
		
		for(int i = 1;i<= cnt;i++)
			for(int j = m;j>= v[i];j--)
				dp[j] = max(dp[j],dp[j-v[i]]+w[i]);
		
		if(m == 1)
			if(s[0] == '1') printf("%d\n",w[1]);
			else printf("0\n");
		else
			printf("%d\n",dp[m]);
	}

	return 0;
}

猜你喜欢

转载自blog.csdn.net/nka_kun/article/details/81605642