Problem C.Storage Keepers 

Background

Randy Company has N (1<=N<=100) storages. Company wants some men to keep them safe. Now there are M (1<=M<=30) men asking for the job. Company will choose several from them. Randy Company employs men following these rules:

1.       Each keeper has a number Pi (1<=Pi<=1000) , which stands for their ability.

2.       All storages are the same as each other.

3.       A storage can only be lookd after by one keeper. But a keeper can look after several storages. If a keeper’s ability number is Pi, and he looks after K storages, each storage that he looks after has a safe number Uj=Pi div K.(Note: Uj, Pi and K are all integers). The storage which is looked after by nobody will get a number 0.

4.       If all the storages is at least given to a man, company will get a safe line L=min Uj

5.       Every month Randy Company will give each employed keeper a wage according to his ability number. That means, if a keeper’s ability number is Pi, he will get Pi dollars every month. The total money company will pay the keepers every month is Y dollars.

Now Randy Company gives you a list that contains all information about N,M,P, your task is give company a best choice of the keepers to make the company pay the least money under the condition that the safe line L is the highest.

Input

The input file contains several scenarios. Each of them consists of 2 lines:

The first line consists of two numbers (N and M), the second line consists of M numbers, meaning Pi (I=1..M). There is only one space between two border numbers.

The input file is ended with N=0 and M=0.

Output

For each scenario, print a line containing two numbers L(max) and Y(min). There should be a space between them.

Sample Input

2 1

7

1 2

10 9

2 5

10 8 6 4 1

5 4

1 1 1 1

0 0

Sample Output

3 7

10 10

8 18

0 0

题意:有m个仓库, n个小伙伴,每个小伙伴有个能力值p,要这些小伙伴去守护仓库,每个小伙伴的雇佣金是p,每个小伙伴看守的仓库安全值为p/k(每个小伙伴看守仓库数)。仓库的安全值为所有仓库中,安全值最小的仓库的安全值。

要求出最大安全值和最大安全值下的最小开销。

思路: 背包, 首先是第一个问题,我们把每个小伙伴看成物品,要看守的仓库数看成背包容量,每个小伙伴看守的仓库数为k,价值为p[i]/k。 状态转移方程为dp[j] = max(dp[j], min(dp[j - k], p[i]/k).。

然后是第二个问题。在第一个问题求出的最大安全值maxx下,求最小价值,依然是背包,k表示每个小伙伴看守的仓库数,状态转移方程为dp[j] = min(dp[j], dp[j - k] + p[i]);

代码:

#include <stdio.h>
#include <string.h> const int INF = 1 << 30;
int n, m, p[105], i, j, k, dp[1005], maxx, minn; int max(int a, int b) {
return a > b ? a : b;
} int min(int a, int b) {
return a < b ? a : b;
} int main() {
while (~scanf("%d%d", &m, &n) && m || n) {
memset(dp, 0, sizeof(dp));
dp[0] = INF;
for (i = 0; i < n; i ++)
scanf("%d", &p[i]);
for (i = 0; i < n; i ++) {
for (j = m; j >= 0; j --) {
for (k = 1; k <= p[i] && k <= j; k ++) {
dp[j] = max(dp[j], min(dp[j - k], p[i] / k));
}
}
}
maxx = dp[m];
if (maxx == 0) {
printf("0 0\n");
continue;
}
for (i = 1; i <= m; i ++)
dp[i] = INF;
dp[0] = 0;
for (i = 0; i < n; i ++)
for (j = m; j >= 0; j --)
for (k = min(j, p[i]/maxx); k > 0; k --) {
dp[j] = min(dp[j], dp[j - k] + p[i]);
}
printf("%d %d\n", maxx, dp[m]);
}
return 0;
}

UVA 10163 Storage Keepers(dp + 背包)的更多相关文章

  1. uva 10163 - Storage Keepers(01背包)

    题目链接:10163 - Storage Keepers 题目大意:给出m为仓库的数量, 给出n为有守夜人的数量, 然后给出n个数值,为对应守夜人应付的酬劳,每个守夜人的能力与他需要的酬劳是相等的,并 ...

  2. UVA 10163 Storage Keepers(两次DP)

    UVA 10163 Storage Keepers(两次DP) http://uva.onlinejudge.org/index.php? option=com_onlinejudge&Ite ...

  3. DP(两次) UVA 10163 Storage Keepers

    题目传送门 /* 题意:(我懒得写,照搬网上的)有n个仓库,m个人看管.一个仓库只能由一个人来看管,一个人可以看管多个仓库. 每个人有一个能力值pi,如果他看管k个仓库,那么所看管的每个仓库的安全值为 ...

  4. UVa 10163 Storage Keepers (二分 + DP)

    题意:有n个仓库,m个管理员,每个管理员有一个能力值P,每个仓库只能由一个管理员看管,但是每个管理员可以看管k个仓库(但是这个仓库分配到的安全值只有p/k,k=0,1,...),雇用的管理员的工资即为 ...

  5. UVA 10163 - Storage Keepers(dp)

    本文出自   http://blog.csdn.net/shuangde800 题目链接: 点击打开链接 题意 有n个仓库,让m个人来看管.一个仓库只能由一个人来看管,一个人可以看管多个仓库. 每个人 ...

  6. uva 10163 Storage Keepers

    题意: 有n个仓库,m个人,一个仓库只能由一个人托管,每个人可以托管多个仓库. 每个人有一个能力值a,如果说他托管了k个仓库,那么这些仓库的安全值都是a/k. 雇佣一个人的花费也是a. 如果一个仓库没 ...

  7. UVA-10163 Storage Keepers (0-1背包)

    题目大意:有n个仓库,m个应聘者,每人对应一个能力值.一个人可以看多个仓库,一间仓库只能被一个人看.如果一个能力为p的人看k间仓库,那么安全系数为p/k,求出最大的最小安全系数,并且求出在此情况下所有 ...

  8. UVA-10163 Storage Keepers DP

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  9. UVA 10163 十六 Storage Keepers

    十六 Storage Keepers Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit ...

随机推荐

  1. [转]中英文停止词表(stopword)

    停止词,是由英文单词:stopword翻译过来的,原来在英语里面会遇到很多a,the,or等使用频率很多的字或词,常为冠词.介词.副词或连词等.如果搜索引擎要将这些词都索引的话,那么几乎每个网站都会被 ...

  2. Working with Strings(使用Oracle字符串)

    Working with Strings By Steven Feuerstein  Part 3 in a series of articles on understanding and using ...

  3. 关于Console的Main(String[] args)参数输入

    之前接触一个往Console里输入参数的项目,资深QA教我怎么run,灰常脸红. 今日无事,baidu之. Step1 写简单Console Code. class Program { static ...

  4. checklistbox的使用

    public class CheckListboxHelper { #region 为checklistbox绑定数据源 /// <summary> /// 为checklistbox绑定 ...

  5. blog开篇

    本来是写java学习开篇的,现在就把它改为博客开篇吧. 其实一直都想着记录一下自己学习的过程,或者说是借口,一直在忙,也从重庆辗转到广州,又从广州辗转到天津了,又一个新阶段开始了,猴年马月都到了,哈哈 ...

  6. 回溯算法————n皇后、素数串

    回溯就是算法是搜索算法中一种控制策略,是一个逐个试探的过程.在试探的过程中,如果遇到错误的选择,就会回到上一步继续选择下一种走法,一步一步的进行直到找到解或者证明无解为止. 如下是一个经典回溯问题n皇 ...

  7. 这是第二道题内容要求写一个银行的ATM系统 这个浪费了好长时间 ,遇到了许多问题,不过都解决了,上程序

    下面的4个用户是我宿舍的,当然我是钱最多的,呵呵! #include<iostream>#include<string>using namespace std; class c ...

  8. Unix下C程序内存泄露检测工具:valgrind的安装使用

    Valgrind是一款用于内存调试.内存泄漏检测以及性能分析的软件开发工具. Valgrind的最初作者是Julian Seward,他于2006年由于在开发Valgrind上的工作获得了第二届Goo ...

  9. mysql学习(五)-字段属性

    字段属性: unsigned: 无符号类型,只能修饰数值类型: create table if not exists t1(id int unsigned); zerofill:前端填0 //只能修饰 ...

  10. asp.net自动打卡、签到程序

    目前公司上下班签到是上局域网的一个系统去点一下,由于打卡比较简单,所以有些快迟到的同事会找已经到公司的人帮忙代打卡.”以其它身份运行程序“来打开IE,去帮人打下,有时多几个人,也要这样操作,我感觉挺麻 ...