1610: 大四上之横扫千军
Time Limit: 1 Sec Memory Limit: 128 MB[ Submit][ Status][ Web Board]
Description
每当夜幕降临,你会想,是时候撸一把了。你手速惊人,所向无敌,并且以超快的速度计算着技能的伤害。然而这时,你浪了一波,被敌军包围。此时你有a点HP和b点MP。并且有n个技能,每个技能刚开始都可以释放,第i个技能的消耗xi点MP,造成yi点HP伤害,zi秒的冷却时间(然而冷却并没有什么卵用,就是说你在任意时刻可以 使用技能最多X次,X是你存活的时间除冷却时间,比如你能活7秒,技能冷却时间是2秒,那么你最多可以使用7/2+1=4次技能,只要技能使用的次数小于4,那么任一时刻,你都可以用)。敌人正以每秒c点HP伤害攻击你。你表示很不服,表示要秀一波,所以你想用仅剩的MP造成尽量多的伤害(可以理解每次都是你先出手)。
Input
第一行输入a,b,c,n.
接下来n行第i输入xi,yi,zi。
输入小于等于100。
Output
输出最大伤害。
Sample Input
50 50 1 2
50 199 100
25 100 50
Sample Output
200
【分析】
本来以为是个...很复杂的dp然而仔细看过题目之后发现...原来题目里都是废话....
其实就是一个背包...每个技能需要x[i]的魔法值,能造成y[i]点伤害,然后这个技能可以释放num[i]次
然后做一个背包看b点魔法值最多可以打出多少伤害就行了
num[i]如何计算题目里也已经给出了。
状态转移方程也是最经典的背包dp的方程:
f[j]=max(f[j],f[j-v[i]+w[i])
【代码】
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int f[1000];
int v[1000];
int w[1000];
int num[1000];
int main()
{
int a,b,c,n;
while (~scanf("%d%d%d%d",&a,&b,&c,&n))
{
if (a%c) a=a/c+1;else a/=c;
memset(f,0,sizeof(f));
for (int i=0;i<n;i++)
{
int z;
scanf("%d%d%d",&v[i],&w[i],&z);
num[i]=a/z+1;
}
for (int i=0;i<n;i++)
for (int k=0;k<num[i];k++)
for (int j=b;j>=v[i];j--)
f[j]=max(f[j],f[j-v[i]]+w[i]);
int ans=0;
for (int i=0;i<=b;i++) ans=max(ans,f[i]);
printf("%d\n",ans);
}
return 0;
}