• 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 }
    编译人生,运行世界!
  • 相关阅读:
    this.$router.push({})实现路由跳转
    JavaScript 实用小技巧
    js中如何实现数组去重--面试题
    面试中知识点积累
    从输入url到网页呈现的过程
    ptyhon学习---作业day1
    python学习---for循环
    python学习---while循环
    python学习---if else流程判断
    ajax最基础入门
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4734023.html
Copyright © 2020-2023  润新知