UVA - 10163Storage Keepers(01背包)

题目大意:UVA - 10163Storage Keepers(01背包)

题目大意:现在有m个守店人,和n家店,每个守店人有个能力值,然后一个守护店的人可以守K家店,那么这些店能到的安全度就是Pi / K。店的安全度取决于守护它的人给的安全度中间最低的那个。这些店的最高安全度取决于最低安全度的那家店。现在问如何雇佣这些人使得店的安全度最高的情况下,费用最少。

解题思路:

安全度要求最高,那么就是要判断每个守店的人要不要雇佣,并且雇佣来之后让它守几家店(安全度)。dp【i】【j】表示:前面的i家店用前面的j个守护人已经守护的时候的这些店的最高安全值。dp【i】【j】 = Max (dp【i】【j - 1】, Min (dp【k】【j - 1】, Pj / k)) k >= 0 && k < i .可以省去j那一维变成滚动数组。

然后这些店的最高安全度出来了ans,现在就是要求花费最少。每家店要维持的安全度出现了,那么雇佣这个人它最多能守护的店的数目最多是Pi / ans,再多的话安全度就不满足要求了,然后就是和前面一样的思路:只是dp【i】【j】变成了前面的i家店用前面的j个守护人的情况下的最低花费(在满足最高安全度)。dp【i】【j】 = Min ((dp【i】【j - 1】,dp【k】【j - 1】 + Pj)。

安全度有要求那么k也就有对应的要求。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <functional>

using namespace std;

const int N = 1005;
const int M = 35;
const int INF = 3000000;

int p[M];
int dp[N];
int y[N];

int Min (const int a, const int b) {return a < b ? a: b; }

int Max (const int a, const int b) {return a > b ? a: b; }

int main () {

	int n, m;
	while (scanf ("%d%d", &n, &m) , n || m) { 

		for (int i = 1; i <= m; i++)
			scanf ("%d", &p[i]);

		sort (p + 1, p + 1 + m, greater<int>());

		memset (dp, 0, sizeof (dp));
		dp[0] = INF;
		for (int i = 1; i <= m; i++)
			for (int j = n; j >= 1; j--) {
				for (int k = 1; k <= j; k++) {
					dp[j] = Max (dp[j], Min (dp[j - k] , p[i] / k));
				}
			}
		int ans = dp[n];

		if (ans) {
			for (int i = 1; i <= n; i++)
				dp[i] = INF;

			dp[0] = 0;
			for (int i = 1; i <= m; i++)
				for (int j = n; j >= 1; j--)
					for (int k = Min(p[i]/ans, j); k >= 1; k--) {

						dp[j] = Min (dp[j], dp[j - k] + p[i]);
					}
		} else
			dp[n] = 0;

		printf ("%d %d\n", ans, dp[n]);	

	}
	return 0;
}

UVA - 10163Storage Keepers(01背包)

时间: 2024-10-24 07:34:39

UVA - 10163Storage Keepers(01背包)的相关文章

Uva 642-CD(0-1背包+打印路径)

题目链接:点击打开链接 裸01背包 ,此题中 价值即体积... 打印路径..不多说了 一维的没看懂..上个二维的 #include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <string> #include <cctype> #include <vector> #include <cstdio>

Uva 10130-SuperSale(0-1背包)

题目链接:点击打开链接 裸的0-1背包 ..只不过相当于有多个背包,因为这些背包互相独立,求和相加就ok #include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <string> #include <cctype> #include <vector> #include <cstdio> #in

UVA 624 CD (01背包+打印路径 或 dfs+记录路径)

Description You have a long drive by car ahead. You have a tape recorder, but unfortunately your best music is on CDs. You need to have it on tapes so the problem to solve is: you have a tape N minutes long. How to choose tracks from CD to get most o

UVA 624 CD (01背包)

//路径记录方法:若是dp[j-value[i]]+value[i]>dp[j]说明拿了这个东西,标志为1, //for循环标志,发现是1,就打印出来,并把背包的容量减少,再在次容量中寻找标志: #include <iostream> #include <cstring> #include <algorithm> using namespace std; int value[30],dp[10001],s[30][10001]; int main() { int

uva 624 CD 01背包打印路径

// 集训最终開始了.来到水题先 #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; int a[23]; int d[23][100000]; int flag[23]; int W,n; void init(){ cin >> n; for (int i=1;i<=n;i++) cin >

UVA 10163-Storage Keepers(DP)

题目大意:有N(1<=N<=100)个仓库需要看管,有M(1<=M<=30)名应聘者,每个人有能力属性Pi(1<=Pi<=1000).所有仓库都是一样的,每个仓库只能被一人看守,一人可看守多个仓库,当一人看守u个仓库时,每个仓库的安全度为Uj=Pi/u,总安全度为min Uj.雇佣一个能力值为Pi的人需要花费Pi元.求最大的总安全度,和在这样的情况下的最小花费. 先dp一次,求出可能的最大总安全度max,再次dp,求出在安全度为max下的最小花费. 第一次dp:用d[i

UVA 562 Dividing coins --01背包的变形

01背包的变形. 先算出硬币面值的总和,然后此题变成求背包容量为V=sum/2时,能装的最多的硬币,然后将剩余的面值和它相减取一个绝对值就是最小的差值. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define N 50007 int c[102],d

UVA - 10032 Tug of War (二进制标记+01背包)

Description Problem F: Tug of War A tug of war is to be arranged at the local office picnic. For the tug of war, the picnickers must be divided into two teams. Each person must be on one team or the other; the number of people on the two teams must n

uva 624 CD (01背包)

uva 624 CD You have a long drive by car ahead. You have a tape recorder, but unfortunately your best music is on CDs. You need to have it on tapes so the problem to solve is: you have a tape N minutes long. How to choose tracks from CD to get most ou