【WOJ 3966】lzy的游戏

【题目】

题目描述:

Leo 最近迷上卡牌游戏,他手上有 n n n 张卡牌,每张卡牌有 2 2 2 个属性分别是伤害值 d i d_i di,魔法值 l i l_i li

玩游戏时,他把卡牌按顺序放在手上,然后每一次他可以选择将最上面在牌打出去,造成 d i d_i di 在伤害,同时会消耗 l i l_i li 张牌(最上面在 l i l_i li 张,包括最上面一张,如果手上在牌不足 l i l_i li 张则不能打出最上面的牌)。如果他不想(不能)打出目前最上面在牌,他可以将最上面在牌放到最下面去。LZY 肯定希望对敌人造成最大的伤害,希望你帮他计算能造成在最大伤害。

输入格式:

第一行是一个数字 n n n

接下来 n n n 行,每行 2 2 2 个数字 d i d_i di l i l_i li 表示每张牌的 2 2 2 个属性

输出格式:

输出一行仅一个数,表示最大伤害

样例数据:

输入
5
2 1
5 3
4 2
1 2
3 1

输出
10

备注:

【数据规模和约定】
对于 30 % 30\% 30% 的数据, 1 1 1 n n n 20 20 20 1 1 1 l i l_i li 20 20 20
对于 100 % 100\% 100% 的数据, 1 1 1 n n n 1000 1000 1000 1 1 1 l i l_i li 100 100 100 1 1 1 d i d_i di 10000 10000 10000


【分析】

口胡一下正解吧(有一些神奇的证明我也不会)

首先是所有要选的牌的 l i l_i li 之和应该小于等于 n n n(应该是很显然的)

然后就是对于任意一组和 l i l_i li 小于等于 n n n 的方案,我们总能够通过调整打牌的顺序来打出这一组牌(感性理解)

这样的话,将 d i d_i di 看做价值,将 l i l_i li 看做价格,直接用 01 01 01背包做就行了

我觉得是非常妙的转化啊


【代码】

#include<cstdio>
#include<algorithm>
#define N 1005
using namespace std;
int f[N];
int main()
{
	int n,i,j,d,l;
	scanf("%d",&n);
	for(i=1;i<=n;++i)
	{
		scanf("%d%d",&d,&l);
		for(j=n;j>=l;--j)
		  f[j]=max(f[j],f[j-l]+d);
	}
	printf("%d",f[n]);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值