P5911 [POI2004]PRZ (状态压缩dp+枚举子集)
题目背景
一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥。
题目描述
桥已经很旧了, 所以它不能承受太重的东西。任何时候队伍在桥上的人都不能超过一定的限制。 所以这只队伍过桥时只能分批过,当一组全部过去时,下一组才能接着过。队伍里每个人过桥都需要特定的时间,
当一批队员过桥时时间应该算走得最慢的那一个,每个人也有特定的重量,我们想知道如何分批过桥能使总时间最少。
输入格式
第一行两个数: W 表示桥能承受的最大重量和 n 表示队员总数。
接下来 n 行:每行两个数: t 表示该队员过桥所需时间和 w 表示该队员的重量。
输出格式
输出一个数表示最少的过桥时间。
输入输出样例
输入 #1
100 3
24 60
10 40
18 50
输出 #1
42
说明/提示
对于 100% 的数据,100≤W≤400,1≤n≤16,1≤t≤50,10≤w≤100。
前置芝士
枚举子集
首先,我们先看一下枚举子集是什么东西。
在状态压缩dp时,我们一般的套路就是枚举两个状态\(i\) 和 \(j\),判断 \(j\) 是否是 \(i\) 的子集,这样来说复杂度时O(4^n)
但,根据二项式定理,一个集合的子集最多有3^n 严格枚举的话,可以将复杂度变为O(3^n)
代码
对于这道题,n的范围很小,我们可以考虑对n进行状态压缩
f[i] 表示达到 \(i\) 这个状态所需要的最小时间 \(i\)时一个n位的二进制数。
转移的话,我们可以枚举\(i\)的子集,就是考虑这次有哪些人乘船
f[i] = min(f[i],f[i-j] + tim[j]);//i是我们想达到的状态,j是这次要运的状态,i-j是没运j这次之前的状态
对于,每个状态所花费的时间,我们可以在之前就预处理出来。
当然,你也可以在枚举j的时候算,只是这样你多算了很多状态,你就会稳稳的TLE
看不懂的童鞋,下面代码有注释。
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,t[20],w[20],base[20],f[65540],tim[65540],maxw[65540];
inline int read()
{
int s = 0, w = 1; char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
while(ch >= '0' && ch <= '9'){s = s * 10+ch -'0'; ch = getchar();}
return s * w;
}
int main()
{
m = read(); n = read();
for(int i = 0; i <= n-1; i++)
{
t[i] = read(); w[i] = read();
}
base[0] = 1;
for(int i = 1; i <= n; i++) base[i] = base[i-1] * 2;//处理一下2的进制
for(int i = 0; i < base[n]; i++)//枚举每个状态
{
for(int j = 0; j < n; j++)//枚举每个人
{
if((i & (1<<j)) == 0)//判断这个人在i这个状态是否已经乘船,没乘船的话,可以转移得到下一个状态
{
tim[i | (1<<j)] = max(tim[i],t[j]);//i|(1<<j)即把i的第j位赋1,就像于第j个人坐了船后,i所变成的状态
maxw[i |(1<<j)] = maxw[i] + w[j]; //进行转移
}
}
}
for(int i = 0; i < base[n]; i++) f[i] = 2333333;//初始化为无穷大
f[0] = 0;
for(int i = 1; i < base[n]; i++)//枚举每个状态
{
for(int j = i; j; j = (j-1) & i)//枚举子集
{
if(maxw[j] <= m) f[i] = min(f[i],f[i-j] + tim[j]);//j你可以理解为这次要运的状态,i-j就是i没运j之前i的状态
}
}
printf("%d\n",f[base[n]-1]);
return 0;
}
P5911 [POI2004]PRZ (状态压缩dp+枚举子集)的更多相关文章
- UVA 11825 - Hackers' Crackdown 状态压缩 dp 枚举子集
UVA 11825 - Hackers' Crackdown 状态压缩 dp 枚举子集 ACM 题目地址:option=com_onlinejudge&Itemid=8&page=sh ...
- 【bzoj2073】[POI2004]PRZ 状态压缩dp
题目描述 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍在桥上的人都不能超过一定的限制. 所以这只队伍过桥时只能分批 ...
- 【bzoj2073】【[POI2004]PRZ】位运算枚举子集的特技
(上不了p站我要死了) Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍在桥上的人都不能超过一 ...
- BZOJ1688|二进制枚举子集| 状态压缩DP
Disease Manangement 疾病管理 Description Alas! A set of D (1 <= D <= 15) diseases (numbered 1..D) ...
- BFS+状态压缩DP+二分枚举+TSP
http://acm.hdu.edu.cn/showproblem.php?pid=3681 Prison Break Time Limit: 5000/2000 MS (Java/Others) ...
- [动态规划]状态压缩DP小结
1.小技巧 枚举集合S的子集:for(int i = S; i > 0; i=(i-1)&S) 枚举包含S的集合:for(int i = S; i < (1<<n); ...
- [NOIP2016]愤怒的小鸟 状态压缩dp
题目描述 Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可以用它向第一象限发射一只红色的小鸟,小鸟们的飞行轨迹均为形 ...
- 状态压缩dp相关
状态压缩dp 状态压缩是设计dp状态的一种方式. 当普通的dp状态维数很多(或者说维数与输入数据有关),但每一维总 量很少是,可以将多维状态压缩为一维来记录. 这种题目最明显的特征就是: 都存在某一给 ...
- hoj2662 状态压缩dp
Pieces Assignment My Tags (Edit) Source : zhouguyue Time limit : 1 sec Memory limit : 64 M S ...
随机推荐
- if-else 可以这么写
最近部门在对以往的代码做一些优化,我在代码中看到一连串的 if(){}elseif(){} 的逻辑判断.这明显是有优化空间的. 由于内部代码不适合分享,这里我就用 <输出今天为星期几> 来 ...
- Java Android程序员软件开发知识:枚举的介绍,以及代码的编写教程。
Java枚举 Java 5.0引入了枚举,枚举限制变量只能是预先设定好的值.使用枚举可以减少代码中的bug. 例如,我们为果汁店设计一个程序,它将限制果汁为小杯.中杯.大杯.这就意味着它不允许顾客点除 ...
- 专项测试实战 | 如何测试 App 流畅度(基于 FPS 和丢帧率)
本文为霍格沃兹测试学院学员学习笔记. FPS 和丢帧率可以在一定程度上作为 APP 流畅度的一项衡量标准,本文介绍利用 adb shell dumpsys gfxinfo 命令获取软件渲染加载过程的数 ...
- stf-多设备管理平台搭建
项目地址: https://github.com/openstf/stf 安装.使用命令 # 安装stfbrew install rethinkdb graphicsmagick zeromq pro ...
- Volatile关键字&&DCL单例模式,volatile 和 synchronized 的区别
Volatile 英文翻译:易变的.可变的.不稳定的. 一.volatile 定义及用法 多个线程的工作内存彼此独立,互不可见,线程启动的时候,虚拟机为每个内存分配一块工作内存,不仅包含了线程内部定义 ...
- POJ-3255-Roadblocks(次短路的另一种求法)
Bessie has moved to a small farm and sometimes enjoys returning to visit one of her best friends. Sh ...
- 基于django快速开发一个网站(一)
基于django快速开发一个网站(一) * 创建虚拟环境.基于虚拟环境创建django==2.0.0和图片加载库和mysql数据库驱动 1. 创建目录并创建虚拟环境 ╰$ mkdir Cornuco ...
- 小程序开发-block组件的使用
微信小程序中,block不是一个组件,而是一个包装元素,不会在页面中做任何渲染. 使用情况:条件渲染 wx:if 因为 wx:if 是一个控制属性,需要将它添加到一个标签/组件上,用于控制隐藏与显示. ...
- 百度网盘,实现免费不限速,10M/S?
前段时间,各大消息都说百度网盘实现了免费和不限速的『提速模式』,可以达到10M/S,于是我带着好奇想要进行测试一下,探一探真假,毕竟只有自己动手实践才知道真理,结果,辜负众望,一向对用户限速还限制上传 ...
- Leetcode 1577 数的平方等于两数乘积的方法数
Leetcode 1577 数的平方等于两数乘积的方法数 题目 给你两个整数数组 nums1 和 nums2 ,请你返回根据以下规则形成的三元组的数目(类型 1 和类型 2 ): 类型 1:三元组 ( ...