题意
度度熊有一张纸条和一把剪刀。
纸条上依次写着 N 个数字,数字只可能是 0 或者 1。
度度熊想在纸条上剪 K 刀(每一刀只能剪在数字和数字之间),这样就形成了 K+1 段。
他再把这 K+1 段按一定的顺序重新拼起来。
不同的剪和接的方案,可能会得到不同的结果。
度度熊好奇的是,前缀 1 的数量最多能是多少。
题解
考场的时候,有点紧张。。想复杂了
很明显,一段1要2次,头的1次,尾的1次
有一种特殊情况,就是拼接在最后的也只用1次
容易想背包。。
但是我“就是拼接在最后的也只用1次”想复杂了,以为有什么特殊情况
今早冷静分析了一下,其实就等价于
k++
k
+
+
然后就是简单背包了
CODE:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100005;
const int K=10005;
char ss[N];
int len;
int n,k;
struct qq
{
int val,cost;
qq () {};
qq (int _cost,int _val) {val=_val;cost=_cost;}
}s[N];int tot=0;
int f[K];
int main()
{
while (scanf("%d%d",&n,&k)!=EOF)
{
scanf("%s",ss+1);len=strlen(ss+1);
int now=0;tot=0;
bool tf=false;
for (int u=1;u<=len;u++)
{
if (ss[u]=='0'&&tf==true)
{
tf=false;
tot++;
if (tot==1&&ss[1]=='1')//这是第一段
s[tot]=qq(1,now);
else s[tot]=qq(2,now);
now=0;
}
if (ss[u]=='1')
{
tf=true;
now++;
}
}
if (tf==true) {tot++;s[tot]=qq(1,now);}
if (k==0)
{
if (ss[1]=='1') printf("%d\n",s[1].val);
else printf("0\n");
continue;
}
k++;
for (int u=0;u<=k;u++) f[u]=0;
for (int u=1;u<=tot;u++)
for (int i=k;i>=0;i--)
if (i>=s[u].cost)
f[i]=max(f[i],f[i-s[u].cost]+s[u].val);
printf("%d\n",f[k]);
}
return 0;
}