• 潜水员(gas)


    【题目描述】

    潜水员为了潜水要使用特殊的装备。他有一个带2种气体的气缸:一个为氧气,一个为氮气。让潜水员下潜的深度需要各种的数量的氧和氮。潜水员有一定数量的气缸。每个气缸都有重量和气体容量。潜水员为了完成他的工作需要特定数量的氧和氮。他完成工作所需气缸的总重的最低限度的是多少?

    例如:潜水员有5个气缸。每行三个数字为:氧,氮的(升)量和气缸的重量:

    3 36 120

    10 25 129

    5 50 250

    1 45 130

    4 20 119

    如果潜水员需要5升的氧和60升的氮则总重最小为249(1,2或者4,5号气缸)。

    你的任务就是计算潜水员为了完成他的工作需要的气缸的重量的最低值。

    【输入】

    第一行有2整数m,n(1≤m≤21,1≤n≤79)。它们表示氧,氮各自需要的量。

    第二行为整数k(1≤n≤1000)表示气缸的个数。

    此后的k行,每行包括ai,bi,ci(1≤ai≤21,1≤bi≤79,1≤ci≤800)3ai,bi,ci(1≤ai≤21,1≤bi≤79,1≤ci≤800)3整数。这些各自是:第i个气缸里的氧和氮的容量及汽缸重量。

    【输出】

    仅一行包含一个整数,为潜水员完成工作所需的气缸的重量总和的最低值。

    【输入样例】

    5 60

    5

    3 36 120

    10 25 129

    5 50 250

    1 45 130

    4 20 119

    【输出样例】

    249

     

    【解题思路】

    1.判断该问题类型:由题意得,该题应使用dp求解。其中每个汽缸都有氧气和氮气两种气体,则该问题为二维费用的背包问题。

    2.判断背包类型:显然,此题中每个汽缸只可取一次,则在使用二维数组的时候应逆序循环。

     

    【代码实现】

     1 #include <algorithm>
     2 #include <cstring>
     3 using namespace std;
     4 int m, n;
     5 int k;
     6 int a[1005], b[1005], c[1005];
     7 int dp[1005][1005];
     8 
     9 int main() {
    10     scanf("%d %d", &m, &n);
    11     scanf("%d", &k);
    12     for (int i = 1; i <= k; i++) {
    13         scanf("%d %d %d", &a[i], &b[i], &c[i]);
    14     }
    15 
    16     memset(dp, 127, sizeof(dp));  // the started
    17     dp[0][0] = 0;                 // don't forget it!
    18     for (int i = 1; i <= k; i++) {
    19         for (int j = m; j >= 0; j--)  // O2
    20         {
    21             for (int h = n; h >= 0; h--)  // N2,the amount of N2 is possible to be 0
    22             {
    23                 int p = j + a[i];
    24                 int q = h + b[i];
    25                 if (p > m) {
    26                     p = m;
    27                 }
    28                 if (q > n) {
    29                     q = n;  //even though p or q is huge,we just need to get the "n" "m" 
    30                     //(用英语写也太费事了!蒟蒻不知道“值”的英文啊) 
    31                 }
    32                 if (dp[p][q] > dp[j][h] + c[i]) {
    33                     dp[p][q] = dp[j][h] + c[i];
    34                 }
    35             }
    36         }
    37     }
    38     printf("%d", dp[m][n]);
    39     return 0;
    40 }
    41 /*
    42 5 60
    43 5
    44 3 36 120
    45 10 25 129
    46 5 50 250
    47 1 45 130
    48 4 20 119
    49 */

    【题外话】

    今天学校旁边的公园门口出了车祸,四死三伤。

    下午上竞赛的时候得知袁隆平老爷子去了。

    青海陕西云南也都发生了地震。

    唉,我们这些尚留在这世间的生命啊,一定要好好活。

  • 相关阅读:
    六十三:CSRF攻击与防御之系统准备之登录与转账功能
    六十二:CSRF攻击与防御之系统准备之注册功能
    六十一:Flask.Session之flask操作session
    并发编程之多进程篇之二
    并发编程之多进程篇之一
    网络编程之文件传输实例
    网络编程基础之粘包现象与UDP协议
    网络编程基础之Socket套接字简单应用
    TCP协议的三次握手和四次挥手
    网络编程基础之Socket套接字
  • 原文地址:https://www.cnblogs.com/TheZealous/p/14799332.html
Copyright © 2020-2023  润新知