uva 10163 - Storage Keepers(01背包)
题目大意:给出m为仓库的数量, 给出n为有守夜人的数量, 然后给出n个数值,为对应守夜人应付的酬劳,每个守夜人的能力与他需要的酬劳是相等的,并且守夜人可以同时负责多个仓库的安全,不过这样子安全值就变为val[i]/k(val[i]表示第i个守夜人的能力值,k表示他负责的仓库数量, /为取整),先在要的出方案,使得所有仓库中安全值最低的那个仓库的安全值越高, 并且要使得酬劳越低。
解题思路:问题应该分成两个子问题来求解,先求安全值最大为多少,然后通过求出的安全值去求解酬劳的最优方案。
1、dp[j] = max(dp[j], min(dp[j - k], val[i] / k)), 可以将max中的两个数值看成是两个方案,是否用min中的方案取代原先的方案。 而min则为该方案中的安全值最低值。(dp[i] 表示保证了i个仓库的安全后的安全值最低值)
2、dp[j] = min(dp[j], dp[j - k] + val[i]), dp[j]表示保证j个仓库的安全值大于ans(第一步求出的最优解)时的花费最小值。
#include <stdio.h>
#include <string.h>
const int N = 1005;
const int M = 105;
const int MAX = 1 << 30;
int max(int a, int b) { return a > b ? a : b; }
int min(int a, int b) { return a < b ? a : b; } int n, m, ans, dp[N], val[M]; int solve() {
memset(dp, 0, sizeof(dp));
dp[0] = 1 << 30;
for (int i = 0; i < n; i++) {
for (int j = m; j >= 0; j--) {
for (int k = 1; k <= j && k <= val[i]; k++)
dp[j] = max(dp[j], min(dp[j - k], val[i] / k));
}
}
return dp[m];
} int find() {
if(ans == 0) return 0;
for (int i = 1; i <= m; i++)
dp[i] = MAX;
dp[0] = 0;
for (int i = 0; i < n; i++) {
for (int j = m; j >= 0; j--) {
for (int k = min(j, val[i] / ans); k > 0; k--)
dp[j] = min(dp[j], dp[j - k] + val[i]);
}
}
return dp[m];
} int main() {
while (scanf("%d%d", &m, &n), n || m) {
for (int i = 0; i < n; i++)
scanf("%d", &val[i]);
ans = solve();
printf("%d %d\n", ans, find());
}
return 0;
}
uva 10163 - Storage Keepers(01背包)的更多相关文章
- UVA 10163 Storage Keepers(dp + 背包)
Problem C.Storage Keepers Background Randy Company has N (1<=N<=100) storages. Company wants ...
- UVA 10163 Storage Keepers(两次DP)
UVA 10163 Storage Keepers(两次DP) http://uva.onlinejudge.org/index.php? option=com_onlinejudge&Ite ...
- DP(两次) UVA 10163 Storage Keepers
题目传送门 /* 题意:(我懒得写,照搬网上的)有n个仓库,m个人看管.一个仓库只能由一个人来看管,一个人可以看管多个仓库. 每个人有一个能力值pi,如果他看管k个仓库,那么所看管的每个仓库的安全值为 ...
- UVa 10163 Storage Keepers (二分 + DP)
题意:有n个仓库,m个管理员,每个管理员有一个能力值P,每个仓库只能由一个管理员看管,但是每个管理员可以看管k个仓库(但是这个仓库分配到的安全值只有p/k,k=0,1,...),雇用的管理员的工资即为 ...
- UVA-10163 Storage Keepers (0-1背包)
题目大意:有n个仓库,m个应聘者,每人对应一个能力值.一个人可以看多个仓库,一间仓库只能被一个人看.如果一个能力为p的人看k间仓库,那么安全系数为p/k,求出最大的最小安全系数,并且求出在此情况下所有 ...
- uva 10163 Storage Keepers
题意: 有n个仓库,m个人,一个仓库只能由一个人托管,每个人可以托管多个仓库. 每个人有一个能力值a,如果说他托管了k个仓库,那么这些仓库的安全值都是a/k. 雇佣一个人的花费也是a. 如果一个仓库没 ...
- UVA 10163 - Storage Keepers(dp)
本文出自 http://blog.csdn.net/shuangde800 题目链接: 点击打开链接 题意 有n个仓库,让m个人来看管.一个仓库只能由一个人来看管,一个人可以看管多个仓库. 每个人 ...
- UVA.10130 SuperSale (DP 01背包)
UVA.10130 SuperSale (DP 01背包) 题意分析 现在有一家人去超市购物.每个人都有所能携带的重量上限.超市中的每个商品有其相应的价值和重量,并且有规定,每人每种商品最多购买一个. ...
- UVA 562 Dividing coins --01背包的变形
01背包的变形. 先算出硬币面值的总和,然后此题变成求背包容量为V=sum/2时,能装的最多的硬币,然后将剩余的面值和它相减取一个绝对值就是最小的差值. 代码: #include <iostre ...
随机推荐
- mysql tee 命令
tee 命令说明: 用过mysql的应该都会知道mysql有一个叫show 的命令,这个命令应该是SQL标准之外的一个扩展:和这个类似mysql还扩展了一个叫tee的命令. tee的功能是把你的所有输 ...
- SQL Server 中可以被锁住的 12 种资源
第1种: DB 整个数据库 第2种: file 数据库文件 第3种: table 第4种: hobt(堆)BTree(B树) 第5种: extent 一个区(8个8KB页面) 第6种: page 数据 ...
- 使用Hashtable和List结合拼json数据
在做项目的时候,有时候需要向页面返回一个特定的json类型的数据,一般情况下会有下面的方法进行拼接: public String chongzhiList() throws Exception { L ...
- 转:Memcached常用命令及使用说明
一.存储命令 存储命令的格式: 1 2 <command name> <key> <flags> <exptime> <bytes> < ...
- Cxf -Wsdl2java详细参数附录
wsdl2java用法: wsdl2java -p com -d src -all aa.wsdl -p 指定其wsdl的命名空间,也就是要生成代码的包名: -d 指定要产生代码所在目录 -cl ...
- 三校联考 Day3
三校联考 Day3 大水题 题目描述:给出一个圆及圆上的若干个点,问两个点间的最远距离. solution 按极角排序,按顺序枚举,显然距离最远的点是单调的,线性时间可解出答案. 大包子的束缚 题目描 ...
- [Leetcode][Python]54: Spiral Matrix
# -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 54: Spiral Matrixhttps://leetcode.com/p ...
- 【Android Training UI】创建自定义Views(Lesson 2 - 自定义Drawing)
发布在我的网站:http://kesenhoo.github.io/blog/2013/06/30/android-training-ui-creating-custom-views-lesson-2 ...
- Malloc碎碎念
(以前为给同学分享写的点东西,很基础.)现在的比赛中堆溢出非常常见,对于glibc下malloc的理解也要深入一些. malloc_chunk的对齐属性 在glibc中,malloc_chunk以 2 ...
- oracle参数文件spfile和pfile
一.参数文件说明 PFILE(Initialiazation Parameter Files)初始化参数文件,是文本文件,可直使用文本编辑器查看.如果数据库使用的是初始化参数文件PFILE,要想永久修 ...