您的位置:首页 > 其它

uva 10163 dp

2015-09-08 11:17 381 查看

UVA 10163 - Storage Keepers

公司有N(1 ≤ N ≤ 100)个仓库,需要安保。现在有M(1 ≤ M ≤ 30)个人应聘职位,每个人有个值P[i] (1 ≤ P[i] ≤ 1000);安排第i个人看守k个仓库,则这k个仓库的安全值是⌊p[i]k⌋≥s\lfloor\frac {p[i]} k\rfloor \ge s,并且花费为Pi。公司要保证所有仓库的最小安全值尽可能的大,求解这个值并且求这个方案的最小花费。

dp[i][j]:表示安排前i个人看守j个仓库能获得的最大的安全值。

考虑第i个人看守了k个仓库,那么前i-1个人需要看守j-k个仓库的最大安全值为dp[i-1][j-k],而后k个仓库的安全值是⌊p[i]k⌋≥s\lfloor\frac {p[i]} k\rfloor \ge s。

dp[i][j] = max(dp[i-1][j], min(dp[i-1][j-k],⌊p[i]k⌋≥s\lfloor\frac {p[i]} k\rfloor \ge s);

由此可以得到最大安全值为s;

要在安全值 >= s的情况下找到最小的花费。

dq[i][j]:表示安排前i个人看守j个仓库在最大的安全值s下的最小花费。

转移同上:

考虑第i个人看守了k个仓库,那么前i-1个人需要看守j-k个仓库的安全值下的花费为dp[i-1][j-k],而后k个仓库的安全值s下的花费是p[i]。当然(⌊p[i]k⌋≥s\lfloor\frac {p[i]} k\rfloor \ge s)

dq[i][j] = min(dq[i-1][j], dp[i-1][j-k] + p[i]);

/*

直接对dp数组路径还原的话总会有一两组数据出错233333

*/

[code]#include <bits/stdc++.h>
using namespace std;

const int INF = 999999999;

int n, m;
int p[350];
int dp[350][1050];
int dq[350][1050];

int main () {
    for (; scanf ("%d%d", &n, &m) == 2; ) {
        if (n == m && m == 0) break;

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

        memset(dq, 0, sizeof(dq));
        memset(dp, 0, sizeof(dp));
        for (int i=1; i<=n; i++) {
            dp[1][i] = p[1] / i;
            dp[i][0] = INF;
        }

        for (int i=2; i<=m; i++) {
            dp[i][1] = max(dp[i-1][1], p[i]);
            for (int j=2; j<=n; j++) {
                dp[i][j] = dp[i-1][j];
                for (int k=1; k<=p[i] && k<=j; k++) {
                    dp[i][j] = max(dp[i][j], min(dp[i-1][j-k], p[i]/k));
                }
            }
        }

        int ans = dp[m]
;
        for (int i=1; i<=n; i++) {
            if (p[1]/i >= ans) dq[1][i] = p[1];
            else dq[1][i] = INF;
        }
        for (int i=2; i<=m; i++) {
            dq[i][1] = dq[i-1][1];
            if (p[i]>=ans) dq[i][1] = min(dq[i-1][1], p[i]);

            for (int j=2; j<=n; j++) {
                dq[i][j] = dq[i-1][j];
                for (int k=1; k<=p[i] && k<=j && p[i]/k >= ans; k++) {
                    dq[i][j] = min(dq[i][j], dq[i-1][j-k] + p[i]);
                }
            }
        }

        if (ans == 0) dq[m]
 = 0;

        cout << dp[m]
 << " ";
        cout << dq[m]
 << endl;

    }

    return 0;
}

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: