题目背景

一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥。

题目描述

桥已经很旧了, 所以它不能承受太重的东西。任何时候队伍在桥上的人都不能超过一定的限制。 所以这只队伍过桥时只能分批过,当一组全部过去时,下一组才能接着过。队伍里每个人过桥都需要特定的时间,

当一批队员过桥时时间应该算走得最慢的那一个,每个人也有特定的重量,我们想知道如何分批过桥能使总时间最少。

输入格式

第一行两个数: 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。

前置芝士

  1. 位运算

  2. 枚举子集

首先,我们先看一下枚举子集是什么东西。

在状态压缩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+枚举子集)的更多相关文章

  1. UVA 11825 - Hackers&#39; Crackdown 状态压缩 dp 枚举子集

    UVA 11825 - Hackers' Crackdown 状态压缩 dp 枚举子集 ACM 题目地址:option=com_onlinejudge&Itemid=8&page=sh ...

  2. 【bzoj2073】[POI2004]PRZ 状态压缩dp

    题目描述 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍在桥上的人都不能超过一定的限制. 所以这只队伍过桥时只能分批 ...

  3. 【bzoj2073】【[POI2004]PRZ】位运算枚举子集的特技

    (上不了p站我要死了) Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍在桥上的人都不能超过一 ...

  4. BZOJ1688|二进制枚举子集| 状态压缩DP

    Disease Manangement 疾病管理 Description Alas! A set of D (1 <= D <= 15) diseases (numbered 1..D) ...

  5. BFS+状态压缩DP+二分枚举+TSP

    http://acm.hdu.edu.cn/showproblem.php?pid=3681 Prison Break Time Limit: 5000/2000 MS (Java/Others)   ...

  6. [动态规划]状态压缩DP小结

     1.小技巧 枚举集合S的子集:for(int i = S; i > 0; i=(i-1)&S) 枚举包含S的集合:for(int i = S; i < (1<<n); ...

  7. [NOIP2016]愤怒的小鸟 状态压缩dp

    题目描述 Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可以用它向第一象限发射一只红色的小鸟,小鸟们的飞行轨迹均为形 ...

  8. 状态压缩dp相关

    状态压缩dp 状态压缩是设计dp状态的一种方式. 当普通的dp状态维数很多(或者说维数与输入数据有关),但每一维总 量很少是,可以将多维状态压缩为一维来记录. 这种题目最明显的特征就是: 都存在某一给 ...

  9. hoj2662 状态压缩dp

    Pieces Assignment My Tags   (Edit)   Source : zhouguyue   Time limit : 1 sec   Memory limit : 64 M S ...

随机推荐

  1. chromevue扩展 vue-devtools-master 谷歌vue的扩展程序

    1,在百度网盘中下载压缩包,网盘地址:https://pan.baidu.com/s/1BnwWHANHNyJzG3Krpy7S8A ,密码:xm6s 2,将压缩包解压到F盘,F:\chromeVue ...

  2. Android开发工具资料Android Manifest 权限描述大全 随时随地查询权限描述。

    作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985转载请说明出处. 在文章最后面赠送了markdown格式的此文章内容下载.(不要再问问什么用markdo ...

  3. gcd(a,b) 复杂度证明

    (b,a%b) a%b<=min(b,a%b)/2 a>=b时每次至少缩减一半 a<b时下次a>b 所以复杂度最多2log(max(a,b)) 证明:a%b<=min(a ...

  4. 万级K8s集群背后etcd稳定性及性能优化实践

    背景与挑战 随着腾讯自研上云及公有云用户的迅速增长,一方面,腾讯云容器服务TKE服务数量和核数大幅增长, 另一方面我们提供的容器服务类型(TKE托管及独立集群.EKS弹性集群.edge边缘计算集群.m ...

  5. 深入了解Kafka【一】概述与基础架构

    1.概述 Kafka是一个分布式的.基于发布订阅的消息系统,主要解决应用解耦.异步消息.流量削峰等问题. 2.发布订阅模型 消息生产者将消息发布到Topic中,同时有多个消息消费者订阅该消息,消费者消 ...

  6. Angular(二) - 组件Component

    1. 组件Component示例 2. Component常用的几个选项 3. Component全部的选项 3.1 继承自@Directive装饰器的选项 3.2 @Component自己特有的选项 ...

  7. 使用vuepress搭建GitHub pages静态博客页面

    vuepress官网 vuepress是尤大开发来写文档的静态页面.可以用Markdown 语法,并且也可以使用vue模块化的方式开发页面. vuepress-theme-reco 是另外的开发者开发 ...

  8. Mybatis源码学习第七天(插件源码分析)

    为了不把开发和源码分析混淆,决定分开写; 接下来分析一下插件的源码,说道这里老套路先说一个设计模式,他就是责任链模式 责任链模式:就是把一件工作分别经过链上的各个节点,让这些节点依次处理这个工作,和装 ...

  9. python3之print()函数

    print语法格式 print()函数具有丰富的功能,详细语法格式如下: print(value, -, sep=' ', end='\n', file=sys.stdout, flush=False ...

  10. Spring Boot入门,源码解析

    目录 1.Spring Boot简介 2.微服务 3.Spring Boot HelloWorld 3.1 创建一个Maven工程 3.2 导入依赖Spring Boot相关的依赖 3.3 编写一个主 ...