百度之星初赛C hdu 6376 度度熊剪纸条

版权声明:本文为博主原创文章,爱转载的表明出处就好. https://blog.csdn.net/qq_36797743/article/details/81604191

题意

度度熊有一张纸条和一把剪刀。
纸条上依次写着 N 个数字,数字只可能是 0 或者 1。
度度熊想在纸条上剪 K 刀(每一刀只能剪在数字和数字之间),这样就形成了 K+1 段。
他再把这 K+1 段按一定的顺序重新拼起来。
不同的剪和接的方案,可能会得到不同的结果。
度度熊好奇的是,前缀 1 的数量最多能是多少。

题解

考场的时候,有点紧张。。想复杂了
很明显,一段1要2次,头的1次,尾的1次
有一种特殊情况,就是拼接在最后的也只用1次
容易想背包。。
但是我“就是拼接在最后的也只用1次”想复杂了,以为有什么特殊情况
今早冷静分析了一下,其实就等价于 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;
}

猜你喜欢

转载自blog.csdn.net/qq_36797743/article/details/81604191