zoukankan      html  css  js  c++  java
  • zoj 3623 Battle Ships

    题意:

    一个游戏,敌人有L的血量,己方可以生产n种武器,每种武器的生产需要花费ti秒,这种武器产生之后的每一秒都可以对敌人的血量造成vi的伤害,并且每种武器的生产数量是没有限制的。

    每一秒要么什么都不做,要么用来生产一种武器。

    当敌人的血量为0时,己方获胜。

    问最少需要多少时间使得己方获胜。

    思路:

    因为每种武器可以生产无数次,所以联想到完全背包。

    如果计算前i秒造成的最大伤害,就会产生一个问题,一个武器生产之后会造成持续伤害,所以实际的状态不好表示。

    换一个思路,把时间当作容量,那么就不必care前多少秒的状态了,只用关心在一个时间段内可以获得的最大伤害。

    转移方程:

    dp[j+t[i]] = max(dp[j+t[i]],dp[j]+j*v[i]).

    对于这个方程的解释是,在j+t[i]这个时间段内,把前t[i]秒(从一开始)用来生产第i个武器,这个武器就在之后的j秒内产生作用,即为j*t[i],然后加上j这个时间段内产生的最大伤害。

    找到第一个dp[i] >= L就是答案。

    代码:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 using namespace std;
     5 const int N = 1000;
     6 int dp[N];
     7 int t[N],v[N];
     8 int main()
     9 {
    10     int n,l;
    11     while (scanf("%d%d",&n,&l)!=EOF)
    12     {
    13         memset(dp,0,sizeof(dp));
    14         for (int i = 0;i < n;i++)
    15         {
    16             scanf("%d%d",&t[i],&v[i]);
    17         }
    18         for (int i = 0;i < n;i++)
    19         {
    20             for (int j = 0;j < l*2;j++)
    21             {
    22                 dp[j+t[i]] = max(dp[j+t[i]],dp[j]+j*v[i]);
    23             }
    24         }
    25         int ans = 0;
    26         for (int i = 0;i < 1000;i++)
    27         {
    28             if (dp[i] >= l)
    29             {
    30                 ans = i;
    31                 break;
    32             }
    33         }
    34         //printf("%d
    ",dp[0]);
    35         printf("%d
    ",ans);
    36     }
    37     return 0;    
    38 }
  • 相关阅读:
    计蒜客 跳跃游戏2
    计蒜客 跳跃游戏
    2018 计蒜之道-初赛 第一场 A-百度无人车
    poj 3625 (最小生成树算法)
    poj 3623(贪心)
    poj2386(dfs搜索水题)
    poj 2761 主席树的应用(查询区间第k小值)
    POJ 2456 编程技巧之------二分查找思想的巧妙应用
    POJ 1995(有关快速幂运算的一道水题)
    1441:【例题2】生日蛋糕
  • 原文地址:https://www.cnblogs.com/kickit/p/8823144.html
Copyright © 2011-2022 走看看