您的位置:首页 > 其它

ZOJ 3623 Battle Ships

2017-01-26 17:36 417 查看
Problem

acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3623

Reference

www.cnblogs.com/andre0506/archive/2012/09/25/2701180.html

题 意

要打倒一座血量为 L 的防御塔,问所需最短时间。

有 N 种战船可以无限制造,每种船给出制造时长 time [i] 和攻击力 lethality [i]。

每一秒都可以选择制造一艘其中一种战船,或者什么都不做。船造好了就一直攻击。

分析

由于每种船的制造数量不限,大概可以想到完全背包模型。

dp [i] :时间 i 内(而不是“在时刻 i”)能造成的最大伤害

然后从短到长找第一个最大伤害大于等于血量的时间。

状态转移:dp [j] = max { dp [j] , dp [j - time [i]] + (j - time [i]) * lethality [i] }

或:dp[j + time[i]] = max { dp[j + time[i]] , dp[j] + j * lethality [i] }

意思就是当时长为 j 时,如果造第 i 种船,就用这段时长最先的 time [i] 秒来造船,这艘新造的船的贡献就是 (j - time [i]) * lethality [i],然后再加上时长为 j - time [i] 时的最大伤害(即 dp [j - time [i]])。

用第2条转移方程来解释就是,在已知时长为 j 时的最大伤害 dp [j] 时,再加上一段长为 time [i] 的时间在 j 这段时间前面用来造船,用新造船的贡献 j * lethality [i] 加上时间 j 的最大伤害 dp [j],得出时长为 j + time [i] 时的一个新的伤害量,看能否比原来的最大伤害 dp [j + time [i]] 大。

Source code

#include <stdio.h>
#include <string.h>
#define N 30
#define L 330
4000
#define T 20

int t
; // 造船时间
int l
; // 船攻击力
int dp[L+T+1];

int max(int a, int b)
{
return a > b ? a : b;
}

int main()
{
int n, hp;
while(~scanf("%d%d", &n, &hp))
{
int i, j;
for(i=0; i<n; ++i)
scanf("%d%d", t+i, l+i);
memset(dp, 0, sizeof dp);
for(i=0; i<n; ++i)
for(j=t[i]; j<=L+T; ++j)
dp[j] = max(dp[j], dp[j-t[i]] + (j-t[i]) * l[i]);
for(i=0; i<=L+T; ++i)
if(dp[i] >= hp)
break;
printf("%d\n", i);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: