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 ...
随机推荐
- SQL Server 索引整理与堆重组。
重新组织索引: alter index idx_OrderID on dbo.OrderDetail reorganize | reorganize;---可以rebuild 也可 ...
- Linux中Samba详细安装
为了实现Windows主机与Linux服务器之间的资源共享,Linux操作系统提供了Samba服务,Samba服务为两种不同的操作系统架起了一座桥梁,使Linux系统和Windows系统之间能够实现互 ...
- Android的数据存储方式(转)
数据存储在开发中是使用最频繁的,在这里主要介绍Android平台中实现数据存储的5种方式,分别是: 1 使用SharedPreferences存储数据 2 文件存储数据 3 SQLite数据库存储数据 ...
- LInux 下挂在Windows共享文件夹
挂载WIndow共享文件夹 //192.168.0.103/software mount -t smbfs -o username=administrator,password=“de123” / ...
- Javascript数组操作方法
1.shift:删除原数组第一项,并返回删除元素的值:如果数组为空则返回undefined var a = [1,2,3,4,5]; var b = a.shift(); //a:[2,3,4,5] ...
- linux文件属性
在Linux中,文件的属性是一个很重要的概念,用户或者用户组对一个文件所拥有的权限,都可以 从文件的属性得知.我们可以通过ls -al命令,列出某个文件夹下面的所有文件(包括以.开头的隐藏 文件).下 ...
- QT 绘制按钮 paintEvent enterEvent leaseEvent mouseEvent
案例2:绘制按钮 main.cpp #include<QApplication> #include “demoWidget.h” int main(int args , int arg ...
- 学用 ASP.Net 之 System.Math 类
本文来自:http://www.cnblogs.com/del/archive/2011/01/03/1924746.html 成员: /* 字段 */ Math.E; //2.7182 ...
- 聚类算法初探(五)DBSCAN
最近由于工作需要,对聚类算法做了一些相关的调研.现将搜集到的资料和自己对算法的一些理解整理如下,供大家参考. 另外在算法代码方面,我也做了一些实现(包括串行和并行),欢迎感兴趣的朋友探讨和交流. 第一 ...
- optimizer for eclipse--Eclipse优化,让你的Eclipse快来飞!
官方网站:http://zeroturnaround.com/free/optimizer-for-eclipse/ infoq网址:http://www.infoq.com/cn/news/2015 ...