uva 10163 storage keeper

来源:互联网 发布:躬匠精神知乎 编辑:程序博客网 时间:2024/06/01 09:50

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

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

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

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

思路:

题目有个限制是:所有物品里面最小的那个安全值即是总的安全值。

第一个dp[i, j] : 前i个人照看前j个物品的最大安全值。

第二个dp[i, j] : 在得到最大安全值的前提下前i个人照看前j个物品的最少花费。

//  Created by Chenhongwei in 2015.//  Copyright (c) 2015 Chenhongwei. All rights reserved.#include"iostream"#include"cstdio"#include"cstdlib"#include"cstring"#include"climits"#include"queue"#include"cmath"#include"map"#include"set"#include"stack"#include"vector"#include"sstream"#include"algorithm"using namespace std;typedef long long ll;int dp[1000], p[100];int main(){//ios::sync_with_stdio(false);// freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);int n, m;while (cin >> n >> m && n + m){for (int i = 1; i <= m; i++)cin >> p[i];memset(dp, 0, sizeof dp);dp[0] = INT_MAX;for (int i = 1; i <= m; i++)for (int j = n; j > 0; j--)for (int k = 1; k <= p[i] && k <= j; k++)dp[j] = max(dp[j], min(dp[j - k], p[i] / k));int maxv = dp[n];if (maxv == 0){cout << "0 0" << endl;continue;}memset(dp, 0x3f, sizeof dp);dp[0] = 0;for (int i = 1; i <= m; i++)for (int j = n; j > 0; j--)for (int k = min(j, p[i] / maxv); k >= 1; k--)dp[j] = min(dp[j], dp[j - k] + p[i]);cout << maxv << ' ' << dp[n] << endl;}return 0;}



0 0
原创粉丝点击