熊熊剪纸条
作者:互联网
Markdown第一次用不太习惯,搞了半天。。。。。。
熊熊剪纸条
度度熊有一张纸条和一把剪刀。
纸条上依次写着 N 个数字,数字只可能是 0 或者 1。
度度熊想在纸条上剪 K 刀(每一刀只能剪在数字和数字之间),这样就形成了 K+1 段。
他再把这 K+1 段按一定的顺序重新拼起来。
不同的剪和接的方案,可能会得到不同的结果。
度度熊好奇的是,前缀 1 的数量最多能是多少。
输入
有多组数据,读到EOF结束。
对于每一组数据,第一行读入两个数 N 和 K 。
第二行有一个长度为 N 的字符串,依次表示初始时纸条上的 N 个数。
0≤K<N≤10000
所有数据 N 的总和不超过100000
输出
对于每一组数据,输出一个数,表示可能的最大前缀 1 的数量。
样例
输入
5 1
11010
5 2
11010
输出
2 3
#include<iostream> #include<cstring> #include<algorithm> using namespace std; int num[100005]; int cmp(int a,int b) { return a>b; } int main() { int n,k; while(scanf("%d%d",&n,&k)==2) { string s; cin>>s; int all=0,i; //所有的1 for(i=0; i<n; i++) if(s[i]=='1') all++; int pre=0; //前面‘连续的1’ for(i=0; i<n; i++) { if(s[i]=='1') pre++; else break; } int left1=0; //后面‘连续的1’ if(pre!=all) {//注意可能字符串s全为1 for(i=n-1; i>=0; i--) { if(s[i]=='1') left1++; else break; } } memset(num,0,sizeof(num)); int j=0,flag; //j:表示中间 ‘连续的1’个数 for(i=pre; i<n-left1; i++) { //储存中间‘连续的1’,用num[]储存起来 flag=0; while(s[i]=='1'&&i<n) { num[j]++; i++; flag=1; } if(flag) j++; } sort(num,num+j,cmp); //中间的‘连续的1’从大到小排序 int sum=0,cur=k; //cur:表示当前剩下的刀数 //开始贪心策略,先处理中间的,注意一定要留下两刀,因为首,尾都只需要一刀就能减掉 for(i=0; i<j&&cur>2; i++) { //中间‘连续的1’,需要用两刀剪 sum+=num[i]; num[i]=0; //用完就删 cur-=2; } //判断最后剩下的两刀 for(i=0; i<j; i++) if(num[i]!=0) break; //找到,中间没剪去的最大‘连续的1’ if(cur>=2) { //如果剩下的刀数 >= 2,就是 num[i],pre,left1,三者之间最大的两个 (原因:请自己在草稿本上演示一下) if(pre<=left1&&pre<=num[i]) sum+=(left1+num[i]); else if(left1<=pre&&left1<=num[i]) sum+=(pre+num[i]); else sum+=(left1+pre); } else if(cur==1) { //剩下刀数 == 1,即 k==3,两种情况:1.剪中间,2.剪尾部(注意剪掉尾部的话,首部的1也可以连上去) sum+=max(num[i],pre+left1); } if(k==0) printf("%d\n",pre); //k==0,就是首部的‘连续的1’ else printf("%d\n",sum); } return 0; }
标签:pre,剪纸,熊熊,int,纸条,num,度度,include 来源: https://www.cnblogs.com/LightyaChoo/p/12716561.html