zoukankan      html  css  js  c++  java
  • 度度熊与邪恶大魔王 DP | 完全背包

    Problem Description

    度度熊为了拯救可爱的公主,于是与邪恶大魔王战斗起来。

    邪恶大魔王的麾下有n个怪兽,每个怪兽有a[i]的生命值,以及b[i]的防御力。

    度度熊一共拥有m种攻击方式,第i种攻击方式,需要消耗k[i]的晶石,造成p[i]点伤害。

    当然,如果度度熊使用第i个技能打在第j个怪兽上面的话,会使得第j个怪兽的生命值减少p[i]-b[j],当然如果伤害小于防御,那么攻击就不会奏效。

    如果怪兽的生命值降为0或以下,那么怪兽就会被消灭。

    当然每个技能都可以使用无限次。

    请问度度熊最少携带多少晶石,就可以消灭所有的怪兽。

    Input

    本题包含若干组测试数据。

    第一行两个整数n,m,表示有n个怪兽,m种技能。

    接下来n行,每行两个整数,a[i],b[i],分别表示怪兽的生命值和防御力。

    再接下来m行,每行两个整数k[i]和p[i],分别表示技能的消耗晶石数目和技能的伤害值。

    数据范围:

    1<=n<=100000

    1<=m<=1000

    1<=a[i]<=1000

    0<=b[i]<=10

    0<=k[i]<=100000

    0<=p[i]<=1000

    Output

    对于每组测试数据,输出最小的晶石消耗数量,如果不能击败所有的怪兽,输出-1

    Sample Input
    1 2
    3 5
    7 10
    6 8
    1 2
    3 5
    10 7
    8 6
    
    Sample Output
    6
    18






    DP
    根据输入的攻击力及耗费的晶石把任意生命力和血量的怪兽处理出来,之后O(1)查找每个怪兽消耗的晶石。时间1000*10*1000(也就7个零)

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<math.h>
     4 #include<algorithm>
     5 #include<string.h>
     6 using namespace std;
     7 __int64 dp[1005][15];
     8 int p[1111], k[1111];
     9 int a[100000 + 5], b[100000 + 5];
    10 int main()
    11 {
    12     int n, m;
    13     while (~scanf("%d%d", &n, &m))
    14     {
    15         int i,j, u;
    16         memset(dp, 111111, sizeof(dp));//初始化
    17         dp[0][0] = 0;
    18         int maxb = 0, maxp = 0;
    19         for (i = 1; i <= n; i++)
    20         {
    21             scanf("%d%d", &a[i], &b[i]);
    22             maxb = max(b[i], maxb);
    23         }
    24         for (i = 1; i <= m; i++)
    25         {
    26             scanf("%d%d", &k[i], &p[i]);
    27             maxp = max(p[i], maxp);
    28         }
    29         //------------特判-----------
    30         if (maxp <= maxb)//最大的攻击力小于等于最大的防御力即不能对此怪造成伤害。
    31         {
    32             printf("-1
    ");
    33             continue;
    34         }
    35         //---------------------------
    36         //-------------血为i 防御力为j------------------
    37         __int64 t, x;
    38         for (i = 1; i <= 1000; i++)
    39         {
    40             for (j = 0; j <= 10; j++)
    41             {
    42                 x = t = dp[i][j];
    43                 for (u = 1; u <= m; u++)
    44                 {
    45                     if (p[u] <= j)
    46                         continue;
    47                     if (p[u] - j >= i)
    48                         x = k[u];
    49                     else
    50                         x = dp[i - p[u] + j][j] + k[u];
    51                     t = min(x, t);
    52                 }
    53                 dp[i][j] = t;
    54             }
    55         }
    56         //-------------------------------------------------
    57         __int64 sum = 0;
    58         for (i = 1; i <= n; i++)
    59         {
    60             sum += dp[a[i]][b[i]];
    61         }
    62         cout << sum << endl;
    63     }
    64 }
  • 相关阅读:
    samba 4.11 or newer version enable SMB1
    linux下使用mv将递归的文件从多个目录移动到一个目录中
    【转载】修改Windows下键盘按键对应功能的一些方案
    ACR122U读卡器在win7以上系统使用过程中的设置项
    恢复Chrome 78以上版本的地址栏https和www显示
    配置sshd的免密码登录
    1234
    MarkDown 语法记录
    语法测试
    解决 Linux grep 不高亮显示
  • 原文地址:https://www.cnblogs.com/jinmingyi/p/7294418.html
Copyright © 2011-2022 走看看