C++标准库:bitset 用法整理&&zoj 3812
题意:给出N种药,每种药有两个属性,重量W,伤害值T。给出Q种疾病,每个疾病也有两个属性:重量M,伤害值S。现在要求你对每种疾病设计选择药的方案,使:1.每种要至多使用一次。2.选出的药的重量的和等于该疾病的重量,选出的药的伤害值的和等于该疾病的伤害值。如果存在方案,输出任何一个方案。否则,输出No solution.
思路:很容易想到这是恰好装满的01背包问题。但是因为T的范围为200000,同时还要输出方案,会感到无从下手。。
我们需要解决的问题有两个:因为T的范围非常大,如何保存dp的状态是个问题。同时也造成了无法直接保存最终的方案。
我们首先求出dp方程。和多重部分和问题不同,这里的选择只有01,所以我们用一个bool类型来表示方案是否存在即可。则设dp[i]j][k]表示考虑前i种药,重量之和为j,伤害值为k的方案是否存在,取值为0或1.状态转移方程为:dp[i+1][j+w[i]][k+t[i]] |= dp[i][j][k]( |= 表示位运算或)。但是,如果直接用int保存该状态,会造成空间的极大浪费。所以我们用bitset类保存该状态,即在第三维用bitset保存。 则状态转移方程为:dp[i+1][j+w[i]][k<<t[i]]
|= dp[i][j][k]。
但是,三维的dp也会爆内存,所以我们用滚动数组的方式来求最终的状态。
而对于第二个问题,我们可以用搜索的方法解决。但是因为爆搜的复杂度是2^400,根本无法进行。在这道题中,我们虽然不能把三维的数组全部开满,但是我们可以将药进行分组,每一组记录一次dp状态,最后再搜索的时候,利用记录还原方案。(自己感觉有点可持久化数据结构的味道)。
代码如下:
using namespace std;
const int MAX = 43;
const int MAXN = 410;
const int MAXA = 51;
const int MAXB = 200001;
int N,Q,T;
int tot,m,s;
int w[MAXN],t[MAXN];
bool sig;
bitset<MAXB> archive[MAX][MAXA],dp[MAXA];
int ans[MAXN],sz;
bool dfs(int n, int m, int s)
{
if(sig) return sig;
if(m == 0 && s == 0){
return sig = true;
}
int now = n / 10;
if(n % 10) now++;
if(archive[now][m][s] == 0)
return false;
if(m >= w[n] && s >= t[n]){
ans[sz++] = n;
if(!dfs(n-1,m - w[n],s - t[n]))
sz--;
}
return dfs(n-1,m,s);
}
int main(void)
{
//freopen("input.txt","r",stdin);
//freopen("out.txt","w",stdout);
scanf("%d", &T);
while(T--){
scanf("%d %d", &N, &Q);
for(int i = 1 ; i <= N; ++i)
scanf("%d %d", &w[i],&t[i]);
for(int i = 0 ; i <= 50; ++i)
dp[i].reset();
tot = 0;
dp[0][0] = 1;
for(int i = 1; i <= N; ++i){
for(int j = 50; j >= w[i]; --j)
dp[j] |= (dp[j - w[i]]<<t[i]);
if(i == N || i % 10 == 0){
tot++;
for(int j = 0; j <= 50; ++j)
archive[tot][j] = dp[j];
}
}
while(Q--){
scanf("%d %d", &m,&s);
if(dp[m][s]){
sz = 0;
sig = false;
dfs(N,m,s);
for(int i = 0; i < sz; ++i)
printf("%d%c",ans[i],i == sz -1?'\n':' ');
}
else
puts("No solution!");
}
}
return 0;
}
</span>
C++标准库:bitset 用法整理&&zoj 3812的更多相关文章
- 把《c++ primer》读薄(3-3 标准库bitset类型)
督促读书,总结精华,提炼笔记,抛砖引玉,有不合适的地方,欢迎留言指正. //开头 #include <bitset> using std::bitset; 问题1.标准库bitset类型( ...
- C++标准库 bitset
本文地址:http://www.cnblogs.com/archimedes/p/cpp-bitset.html,转载请注明源地址. 有些程序要处理二进制位的有序集,每个位可能包含 0(关)1(开)值 ...
- C++标准库bitset类型(简单使用方法)
转自此人博客 ```cpp #include<bister> using std::bitset; ``` 一句话定义:可自定义位数,用作记录二进制的数据类型. 一,定义和初始化 ```c ...
- C++ 标准库类型-String,Vector and Bitset
<C++ Primer 4th>读书摘要 最重要的标准库类型是 string 和 vector,它们分别定义了大小可变的字符串和集合.这些标准库类型是语言组成部分中更基本的那些数据类型(如 ...
- 【BZOJ 1923】1923: [Sdoi2010]外星千足虫 (高斯消元异或 | BITSET用法)
1923: [Sdoi2010]外星千足虫 Description Input 第一行是两个正整数 N, M. 接下来 M行,按顺序给出 Charles 这M次使用“点足机”的统计结果.每行 包含一个 ...
- C++primer第三章标准库类型
除第二章介绍的基本数据类型外,C++ 还定义了一个内容丰富的抽象数据类型标准库. 本章将介绍标准库中的 vector.string 和 bitset 类型. string 类型支持长度可变的字符串 v ...
- 1.Python3标准库--前戏
Python有一个很大的优势便是在于其拥有丰富的第三方库,可以解决很多很多问题.其实Python的标准库也是非常丰富的,今后我将介绍一下Python的标准库. 这个教程使用的书籍就叫做<Pyth ...
- Primer回顾 标准库类型
string类型的输入操作符: 1.读取并忽略开头所有的空白字符(如空格,换行符,制表符). 2.读取字符直至再次遇到空白字符,读取终止. 用getline读取整行文本 getline.接受两个参 ...
- 《JavaScript语言入门教程》记录整理:运算符、语法和标准库
目录 运算符 算数运算符 比较运算符 布尔运算符 二进制位运算符 void和逗号运算符 运算顺序 语法 数据类型的转换 错误处理机制 编程风格 console对象和控制台 标准库 Object对象 属 ...
随机推荐
- [Swift]Array(数组)扩展
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- Django day 33 vue中使用element-ui的使用,课程的相关介绍,vue绑定图片,课程列表接口,课程详情页面
一:vue中使用element-ui的使用, 二:课程的相关介绍, 三:vue绑定图片, 四:课程列表接口, 五:课程详情页面
- 源码阅读之ArrayList(JDK8)
ArrayList概述 ArrayList是一个的可变数组的实现,实现了所有可选列表操作,并允许包括 null 在内的所有元素.每个ArrayList实例都有一个容量,该容量是指用来存储列表元素的数组 ...
- Mybatis Generator插件升级版
一.目的: 1. *mapper.java 文件名称 改为*DAO.java2. mapper以及mapper.xml 重复执行,只会覆盖原模板方法,不会覆盖自定义方法3. 实体类添加中文注释 二.步 ...
- laravel生命周期和核心思想
工欲善其事,必先利其器.在开发Xblog的过程中,稍微领悟了一点Laravel的思想.确实如此,这篇文章读完你可能并不能从无到有写出一个博客,但知道Laravel的核心概念之后,当你再次写起Larav ...
- [C++ STL] list使用详解
一.list介绍: List由双向链表(doubly linked list)实现而成,元素也存放在堆中,每个元素都是放在一块内存中,他的内存空间可以是不连续的,通过指针来进行数据的访问,这个特点使得 ...
- python批量下载图片
从数据库拿了一批图片地址,需要一张一张的把图片下载下来,自从有了python,想到能省事就琢磨如何省事. 代码如下: import urllib.requestf=open("E:\999\ ...
- 279 Perfect Squares 完美平方数
给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...) 使得他们的和等于 n.你需要让平方数的个数最少.比如 n = 12,返回 3 ,因为 12 = 4 + 4 + 4 : ...
- 基于SOC方案的嵌入式开发-远程定时设备
Soc方案实现简单的定时开关灯 http://club.gizwits.com/forum.php?mod=viewthread&tid=7787&highlight=%E5%AE%9 ...
- eclipse中添加maven
收藏一下,一篇很好的例子 maven相关插件:链接:http://pan.baidu.com/s/1i3Ks95j 密码:7pgh eclipse:链接:http://pan.baidu.com/s/ ...