题目:度度熊有一张纸条和一把剪刀。


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


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



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



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



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

题目大意:……不用大意了原题目已经说的很清楚了。

分析:我们这一串数字中,前缀的1可以直接算在答案里,后缀的1可以花费一刀剪掉,中间的1需要花费两刀剪掉,如图:

    

这样我们就可以把每一堆1所组成的组作为01背包中的一个单位,以其中1的数量为w,以k为容量做01背包。(我们把前缀的1的体积设为0,后缀1的体积设为1,中间的设为2)。然后做基础的01背包即可。

ps:直接贪心也可以解,给中间的1们按数量排序,然后从大到小加和,再比较一下是否加后缀也可以,但是需要考虑的细节太多(一晚上的头发你付的起吗),适合代码实现能力较强的同学尝试。

然后就

完了吗?

当然不是,你按照刚才我说的去打,一定会WA!!!!!!!!!

我们试想一组例子:

7 1

1011101

按照我们们刚才的想法,一定会得出2,实际上组样例的结果是3!!!

因为这组样例中出现了“中间比前缀更优的情况”。

我们一般会认为,前缀一块钱不花,白给的谁不要啊?这就犯了错误了,你在中间划一刀可能更优!

所以我们在比较时候需要让前缀1和其他1“公平竞争”,可以把它的体积设置为1,然后总容量k++,这样每次先遍历它的时候自然会把他加进去,而剩余容量也不变,如果遇到更好的,把它换走就好了。

我们还可以深入研究一下为什么要背包容量++。

事实上我们看1011101与0011101这两组数据,你砍两刀,结果都是4。

这是为什么呢?我们注意到,排位靠前的中缀1其实代价为1而不是2。

说起来也很好理解:你砍完一刀,中缀1的“1”就已经露出来了,你只需要把其他的往他上面粘就可以了。而前缀相当于一个默认“露头”的中缀1。

所以与其随机找到最大的中缀1让他的代价-1,还不如直接扩容背包,而前缀1其实是霸占了那个“优秀的”中缀1 的位置的。你若0代价选前缀,那么就不存在中缀砍1刀就出结果的过程了,所以我们为了不默认前缀1是那个被代价-1的,所以给他代价+1,这样在扩容背包,所有的1就都平等竞争了,不会存在谁“优秀”的问题了

思路清晰了,上代码!!!

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e5+10;
int a[maxn],v[maxn],w[maxn],f[maxn];
int n,k,cnt,Max;
char s[maxn];
int main(){
while(scanf("%d%d",&n,&k)!=EOF){
memset(a,0,sizeof(a));
memset(f,0,sizeof(f));
memset(w,0,sizeof(w));
memset(v,0,sizeof(v));
cnt=0;
//一些无聊的初始化
scanf("%s",s);
for(int i=1;i<=n;i++){
a[i]=s[i-1]-'0';
}//用整形存,可不用。
for(int i=1;i<=n;i++){
if(a[i]==1){
cnt++;//含1的组数++
v[cnt]=2;
while(a[i]==1&&i<n+1){
i++;
w[cnt]++;//这个组1的数量
}
}
} if(a[1]==1){
v[1]=1;
}
if(a[n]==1){
v[cnt]=1;
}
k++;
//第一块与最后一块的代价是1
if(k==1){
if(a[1]==1){
printf("%d\n",w[1]);
continue;
}else{
printf("0\n");
continue;
}
}//这里k==1,就是一刀都不让你切,直接等于前缀和
for(int i=1;i<=cnt;i++){
for(int j=k;j>=v[i];j--){
f[j]=max(f[j],f[j-v[i]]+w[i]);
}
}//01背包标准式
printf("%d\n",max(f[k],Max));
} return 0;
}

hdu6376 度度熊剪纸条-----01背包的更多相关文章

  1. hdu6376 度度熊剪纸条 思维

    度度熊剪纸条 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Subm ...

  2. hdu6376 度度熊剪纸条

    思路: 01背包.有些细节需要注意一下,比如k = 0的情况. 实现: #include <bits/stdc++.h> using namespace std; typedef pair ...

  3. HDU-6376 度度熊剪纸条

    链接 http://acm.hdu.edu.cn/showproblem.php?pid=6376 分析 这道题好像不是很难,因为是要拼出前缀1,所以确定剪下每一段1需要的刀数,然后因为有次数限制,所 ...

  4. HDU 6083 度度熊的午饭时光(01背包+记录路径)

    http://acm.hdu.edu.cn/showproblem.php?pid=6083 题意: 思路: 01背包+路径记录. 题目有点坑,我一开始逆序枚举菜品,然后一直WA,可能这样的话路径记录 ...

  5. 百度之星资格赛 1004 度度熊的午饭时光(01背包+最小序号和+字典序+有bug)

    分析 首先声明一下,我的代码有漏洞的,求大神给个正确代码 思路如下: 首先做一遍01背包记录路径并求出最大总分,令path[i][j]表示第i个物品包含在dp[j]的求值过程中.再逆序枚举money, ...

  6. 2017"百度之星"程序设计大赛 - 初赛(A) [ hdu 6108 小C的倍数问题 ] [ hdu 6109 数据分割 ] [ hdu 6110 路径交 ] [ hdu 6112 今夕何夕 ] [ hdu 6113 度度熊的01世界 ]

    这套题体验极差. PROBLEM 1001 - 小C的倍数问题 题 OvO http://acm.hdu.edu.cn/showproblem.php?pid=6108 (2017"百度之星 ...

  7. HDU 6113 度度熊的01世界

    度度熊的01世界 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  8. HDU 6113 度度熊的01世界【DFS/Flood Fill】

    度度熊的01世界 Accepts: 967 Submissions: 3064 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/3 ...

  9. HDU - 6113 2017百度之星初赛A 度度熊的01世界

    度度熊的01世界  Accepts: 967  Submissions: 3064  Time Limit: 2000/1000 MS (Java/Others)  Memory Limit: 327 ...

随机推荐

  1. .NET Core 下使用 Apollo 配置中心

    Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境.不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限.流程治理等特性,适用于微服务配置管理场景.服务 ...

  2. 判断语句 、 while循环 、 for循环

    判断语句 语法结构 if 条件1: 如果条件1为真,执行语句块 elif 条件2: 如果条件2为真,执行语句块 elif 条件3: 如果条件2为真,执行语句块 elif 条件n: 如果条件n为真,执行 ...

  3. jni之jni与jna的比较

    java开发过程中会遇到需要调用c/c++动态库(windows平台的dll和linux平台的so)的情况,可以使用JNI或者JNA技术. JNA基于JNI技术开发,主要在上层作了类型自动转换的封装, ...

  4. 大量数据也不在话下,Spring Batch并行处理四种模式初探

    1 前言 欢迎访问南瓜慢说 www.pkslow.com获取更多精彩文章! Spring相关文章:Springboot-Cloud 前面写了一篇文章<通过例子讲解Spring Batch入门,优 ...

  5. pycharm写的代码提交到git上,提示需要merge失败时解决办法

    当遇到pycharm代码提交需要合并报错时 原因:pycharm目录和git中目录冲突了 解决办法:1.先在git仓库中创建一个文件夹,比如day1 2.然后在pycharm中update一下,可以看 ...

  6. 云计算openstack核心组件——neutron网络服务(8)

    一.neutron 介绍:   Neutron 概述 传统的网络管理方式很大程度上依赖于管理员手工配置和维护各种网络硬件设备:而云环境下的网络已经变得非常复杂,特别是在多租户场景里,用户随时都可能需要 ...

  7. ansible-doc到底有多好用,助你玩转各种模块

    #使用ansible-doc:查看各种模块的帮助 #命令格式: ansible-doc -l #列出所有的模块列表 ansible-doc -s 模块名 #查看指定模块的参数 ansible-doc ...

  8. a标签包裹div的问题

    示例代码 1 <a href="#"> 2 <div> 3 <a href="#"></a> 4 </di ...

  9. MySQL手注之联合查询注入

    了解联合查询注入之前,先要了解一下什么是union? union是用于合并两个sql查询结果的语句. 要使用union 必须有相同的列数  必须有两条以上的select语句组成  列的数据类型必须兼容 ...

  10. leetcode1558题解【贪心】

    leetcode1558.得到目标数组的最少函数调用次数 题目链接 算法 贪心 时间复杂度O(nlogN),N为数组中最大的那个数. 1.题意就是给定一个函数,该函数有两种功能,一种就是将数组中的所有 ...