ZOJ 3623 Battle Ships

31 篇文章 0 订阅

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
#define T 20

int t[N]; // 造船时间
int l[N]; // 船攻击力
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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值