zoukankan      html  css  js  c++  java
  • DP(两次) UVA 10163 Storage Keepers

    题目传送门

     1 /*
     2    题意:(我懒得写,照搬网上的)有n个仓库,m个人看管。一个仓库只能由一个人来看管,一个人可以看管多个仓库。
     3         每个人有一个能力值pi,如果他看管k个仓库,那么所看管的每个仓库的安全值为 pi/k(向下取整)
     4         如果某个仓库没有人看管,那么它的安全值为0。所有仓库的安全值L = min{ 每个仓库的安全值 }
     5         从m个人中选择一些人雇佣,问所有仓库的安全值最高是多少,在安全值最高的情况下,求雇佣(能力值)的最少价钱。
     6     DP(两次):dp[i][j]表示前i个人管理j个仓库的最大安全值,那么dp[i][j] = max (dp[i-1][j-k], p[i] / k) (k是当前选择的仓库数)
     7             在保障最大安全值下选择最小花费,也就是:p[i] / k >= dp[m][n]下,dp2[i][j]表示前i个人管理了j个仓库所需最小花费
     8     这题我想了一上午,同时考虑安全值和花费的最优,结果越弄越乱,依据题意应该安全第一!
     9  */
    10 /************************************************
    11  * Author        :Running_Time
    12  * Created Time  :2015-8-16 9:59:59
    13  * File Name     :UVA_10163.cpp
    14  ************************************************/
    15 
    16 #include <cstdio>
    17 #include <algorithm>
    18 #include <iostream>
    19 #include <sstream>
    20 #include <cstring>
    21 #include <cmath>
    22 #include <string>
    23 #include <vector>
    24 #include <queue>
    25 #include <deque>
    26 #include <stack>
    27 #include <list>
    28 #include <map>
    29 #include <set>
    30 #include <bitset>
    31 #include <cstdlib>
    32 #include <ctime>
    33 using namespace std;
    34 
    35 #define lson l, mid, rt << 1
    36 #define rson mid + 1, r, rt << 1 | 1
    37 typedef long long ll;
    38 const int MAXN = 1e2 + 10;
    39 const int MAXM = 33;
    40 const int INF = 0x3f3f3f3f;
    41 const int MOD = 1e9 + 7;
    42 int dp[MAXM][MAXN], dp2[MAXM][MAXN];
    43 int p[MAXM];
    44 
    45 int main(void)    {     //UVA 10163    Storage Keepers
    46     int n, m;
    47     while (scanf ("%d%d", &n, &m) == 2) {
    48         if (!n && !m)   break;
    49         for (int i=1; i<=m; ++i)    scanf ("%d", &p[i]);
    50         memset (dp, 0, sizeof (dp));
    51         for (int i=1; i<=m; ++i)    {
    52             dp[i-1][0] = INF;
    53             for (int j=1; j<=n; ++j)    {
    54                 dp[i][j] = dp[i-1][j];
    55                 for (int k=1; k<=j; ++k)    {
    56                     dp[i][j] = max (dp[i][j], min (dp[i-1][j-k], p[i] / k));
    57                 }
    58             }
    59         }
    60         memset (dp2, INF, sizeof (dp2));
    61         for (int i=1; i<=m; ++i)    {
    62             dp2[i-1][0] = 0;
    63             for (int j=1; j<=n; ++j)    {
    64                 dp2[i][j] = dp2[i-1][j];
    65                 for (int k=1; k<=j; ++k)    {
    66                     int s = p[i] / k;
    67                     if (s >= dp[m][n])  {
    68                         dp2[i][j] = min (dp2[i][j], dp2[i-1][j-k] + p[i]);
    69                     }
    70                 }
    71             }
    72         }
    73 
    74         printf ("%d %d
    ", dp[m][n], (dp[m][n] == 0) ? 0 : dp2[m][n]);
    75     }
    76 
    77     return 0;
    78 }
    编译人生,运行世界!
  • 相关阅读:
    linux 命令——19 find (转)
    linux 命令——18 locate (转)
    linux 命令——17 whereis(转)
    linux 命令——16 which(转)
    linux 命令——15 tail (转)
    linux 命令——14 head (转)
    Java for LeetCode 038 Count and Say
    Java for LeetCode 037 Sudoku Solver
    Java for LeetCode 036 Valid Sudoku
    Java for LeetCode 035 Search Insert Position
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4734023.html
Copyright © 2011-2022 走看看