UVA-10163 Storage Keepers (DP多次)
2016-04-28 09:21
337 查看
Randy Company has
N (1
≤ N
≤ 100) storages. Company wants some men to keep them safe. Nowthere are
M (1
≤ M
≤ 30) men asking for the job. Company will choose several from them. RandyCompany employs men following these rules:
Each keeper has a number
Pi (1
≤ Pi
≤ 1000) , which stands for their ability.
All storages are the same as each other.
A storage can only be lookd after by one keeper. But a keeper can look after several storages. If akeeper’s ability number is
Pi, and he looks after
K storages, each storage that he looks after hasa safe number
Uj
= Pi
÷ K.(Note:
Uj,
Pi
and K are all integers). The storage which is lookedafter by nobody will get a number 0.
If all the storages is at least given to a man, company will get a safe line
L = min
Uj
Every month Randy Company will give each employed keeper a wage according to his abilitynumber. That means, if a keeper’s ability number is
Pi, he will get
Pi
dollars every month. Thetotal 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 givecompany a best choice of the keepers to make the company pay the least money under the conditionthat 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 spacebetween them.
Sample Input
21
7
12
10 9
25
10 8 6 4 154111100
Sample Output
3710 108 1800
题意:
给你n个仓库,m个人,第i个人的能力值为pi,每个人可守卫多个仓库,每个仓库只能被一人守卫,若第i个人守护k个仓库,则那些仓库的安全值为pi/k的整数部分,设所有仓库中安全值最低的为t,要求t最大的情况下,消耗最少的能力值。
分析:
第一次dp,求出n个仓库m个人可获得的最大的t。
f[i][j]表示前i个人守护j个仓库的最低安全值,可得f[i][j]=max(f[i][j],min(pi/k,f[i-1][j-k]))
第二次dp,求出在安全值为t的情况下,消耗最少的能力值。
g[i][j]表示前i个人守护j个仓库在安全值最大情况下花费最少的能力值,可得当pi/k>=f[m]
时,g[i][j]=min(g[i][j],g[i-1][j-k]+pi)
以上k均表示第i个人守护k个仓库时的情况。#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;
#define INF 0x3f3f3f3f
const int N=105;
const int mod=1e9+7;
int p
,f
,g
;
int main() {
int n,m;
while (cin>>n>>m&&n) {
for (int i=1; i<=m; i++) {
cin>>p[i];
}
memset(f, 0, sizeof(f));
memset(g, INF, sizeof(g));
for (int i=1; i<=m; i++) {
f[i-1][0]=INF;
for (int j=1; j<=n; j++) {
f[i][j]=f[i-1][j];
for (int k=1; k<=j; k++) {
f[i][j]=max(min(p[i]/k, f[i-1][j-k]),f[i][j]);
}
}
}
if (f[m]
==0) {
g[m]
=0;
} else {
for (int i=1; i<=m; i++) {
g[i-1][0]=0;
for (int j=1; j<=n; j++) {
g[i][j]=g[i-1][j];
for (int k=1; k<=j; k++) {
if (p[i]/k>=f[m]
) {
g[i][j]=min(g[i][j], g[i-1][j-k]+p[i]);
}
}
}
}
}
cout<<f[m]
<<" "<<g[m]
<<endl;
}
return 0;
}
N (1
≤ N
≤ 100) storages. Company wants some men to keep them safe. Nowthere are
M (1
≤ M
≤ 30) men asking for the job. Company will choose several from them. RandyCompany employs men following these rules:
Each keeper has a number
Pi (1
≤ Pi
≤ 1000) , which stands for their ability.
All storages are the same as each other.
A storage can only be lookd after by one keeper. But a keeper can look after several storages. If akeeper’s ability number is
Pi, and he looks after
K storages, each storage that he looks after hasa safe number
Uj
= Pi
÷ K.(Note:
Uj,
Pi
and K are all integers). The storage which is lookedafter by nobody will get a number 0.
If all the storages is at least given to a man, company will get a safe line
L = min
Uj
Every month Randy Company will give each employed keeper a wage according to his abilitynumber. That means, if a keeper’s ability number is
Pi, he will get
Pi
dollars every month. Thetotal 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 givecompany a best choice of the keepers to make the company pay the least money under the conditionthat 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 spacebetween them.
Sample Input
21
7
12
10 9
25
10 8 6 4 154111100
Sample Output
3710 108 1800
题意:
给你n个仓库,m个人,第i个人的能力值为pi,每个人可守卫多个仓库,每个仓库只能被一人守卫,若第i个人守护k个仓库,则那些仓库的安全值为pi/k的整数部分,设所有仓库中安全值最低的为t,要求t最大的情况下,消耗最少的能力值。
分析:
第一次dp,求出n个仓库m个人可获得的最大的t。
f[i][j]表示前i个人守护j个仓库的最低安全值,可得f[i][j]=max(f[i][j],min(pi/k,f[i-1][j-k]))
第二次dp,求出在安全值为t的情况下,消耗最少的能力值。
g[i][j]表示前i个人守护j个仓库在安全值最大情况下花费最少的能力值,可得当pi/k>=f[m]
时,g[i][j]=min(g[i][j],g[i-1][j-k]+pi)
以上k均表示第i个人守护k个仓库时的情况。#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;
#define INF 0x3f3f3f3f
const int N=105;
const int mod=1e9+7;
int p
,f
,g
;
int main() {
int n,m;
while (cin>>n>>m&&n) {
for (int i=1; i<=m; i++) {
cin>>p[i];
}
memset(f, 0, sizeof(f));
memset(g, INF, sizeof(g));
for (int i=1; i<=m; i++) {
f[i-1][0]=INF;
for (int j=1; j<=n; j++) {
f[i][j]=f[i-1][j];
for (int k=1; k<=j; k++) {
f[i][j]=max(min(p[i]/k, f[i-1][j-k]),f[i][j]);
}
}
}
if (f[m]
==0) {
g[m]
=0;
} else {
for (int i=1; i<=m; i++) {
g[i-1][0]=0;
for (int j=1; j<=n; j++) {
g[i][j]=g[i-1][j];
for (int k=1; k<=j; k++) {
if (p[i]/k>=f[m]
) {
g[i][j]=min(g[i][j], g[i-1][j-k]+p[i]);
}
}
}
}
}
cout<<f[m]
<<" "<<g[m]
<<endl;
}
return 0;
}
相关文章推荐
- Pixhawk编译环境搭建-Ubuntu
- 用人三境界:用师者王,用友者霸,用徒者亡
- iOS中使用脚本打包项目
- 第九周练习 阅读程序
- 第9周项目1——3
- App上架出现问题-ERROR ITMS-90034
- ajax 无刷新 文件上传
- 第9周(2)
- 第九周项目3-人数不定的工资类2
- linux下svn服务器安装配置与启动
- Oracle多表关联更新(update多表关联)
- C#发送post请求支持发送文件
- SQL细节
- 设计模式(七): 通过转接头来观察"适配器模式"(Adapter Pattern)
- zabbix中文乱码解决方法
- 多重继承中派生类的构造函数和析构函数
- iOS开发之运动事件和远程控制
- C#编写的基于VLC的播放器
- php编程中require和include多层嵌套导致文件找不到的错误
- 第九周阅读项目-(3)