UVa 10163 仓库守卫

https://vjudge.net/problem/UVA-10163

题意:

有n个仓库,m个管理员,每个管理员有一个能力值P(接下来的一行有m个数,表示每个管理员的能力值)

每个仓库只能由一个管理员看管,但是每个管理员可以看管k个仓库(但是这个仓库分配到的安全值只有p/k,k=0,1,...),

每个月公司都要给看管员工资,雇用的管理员的工资即为他们的能力值p和,问,使每个仓库的安全值最高的前提下,使的工资总和最小。

输出最大安全值,并且输出最少的花费。

 

思路:

先求出安全系数来。d[i][j]表示前i个守卫看守前j个仓库的最小安全系数的最大值。之后第二次DP求最小花费。

 1 #include<iostream> 
 2 #include<string>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int maxn = 10000 + 5;
 8 const int INF = 10000000;
 9 
10 int n, m;
11 int p[35];
12 int d[maxn][maxn];
13 
14 int main()
15 {
16     //freopen("D:\\txt.txt", "r", stdin);
17     while (cin >> n >> m && n&& m)
18     {
19         for (int i = 1; i <= m; i++)
20             cin >> p[i];
21         for (int i = 0; i <= m; i++)
22             d[i][0] = INF;
23         for (int i = 1; i <= n; i++)
24             d[0][i] = 0;
25         for (int i = 1; i <= m; i++)
26         {
27             for (int j = 1; j <= n; j++)
28             {
29                 d[i][j] = d[i - 1][j];
30                 for (int k = 0; k < j; k++)
31                     d[i][j] = max(d[i][j], min(d[i - 1][k], p[i] / (j - k)));
32             }
33         }
34         if (!d[m][n])
35         {
36             cout << "0 0" << endl;
37             continue;
38         }
39         int x = d[m][n];
40         for (int i = 0; i <= m; i++)
41             d[i][0] = 0;
42         for (int i = 1; i <= n; i++)
43             d[0][i] = INF;
44         for (int i = 1; i <= m;i++)
45         for (int j = 1; j <= n; j++)
46         {
47             d[i][j] = d[i - 1][j];
48             for (int k = 0; k < j;k++)
49             if (p[i] / (j-k) >= x)
50                 d[i][j] = min(d[i][j], d[i - 1][k] + p[i]);
51         }
52         cout << x << " " << d[m][n] << endl;
53     }
54     return 0;
55 }

 

posted @ 2017-02-09 15:03  Kayden_Cheung  阅读(216)  评论(0编辑  收藏  举报
//目录