魔兽 DP
Posted 古时候的瘾君子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了魔兽 DP相关的知识,希望对你有一定的参考价值。
【问题描述】
你玩过魔兽争霸么?不管你玩的好不好都不要紧!在玩游戏的同时,我们有这样的体验。
游戏中有很多英雄,但是你只能选择其中之一。每个英雄都有自己的技能。当一个技能被使
用,它的代价是在花费英雄的一定的魔力值,也在同一时间伤害 boss。你在使用技能要根据
情报,应该在伤害敌人最大的时候的使用某些魔力技能。
现在我们送你去完成这样一个任务杀死 boss。为了简化这个问题:我们假设 boss 怪物
的生命值是 100,你的也是 100,你的魔力值也是 100 !你和 boss 轮流进行攻击,并且你先手,
你每次攻击 boss 耗时 1 秒。
每次你可以选择使用普通攻击(不花魔力),或一个特定的技能(条
件是你的现有魔力值不低于技能的花费成本(魔力值),天下没有免费的午餐,所以你在支付
一定的魔力之后你才能使用这个技能!但我们是足够好,为您提供一个魔力恢复指环(每秒钟
可以恢复一些的魔力值),但是你不能拥有超过 100 魔力值上限 和 只要魔力没有达到上限,
就总是在恢复。Boss 是 cruel,小心!
【输入文件】
多组测试数据
每组数据的第一行输入 3 个整数 n ,t ,q (0 < n < = 100,1 < = t < = 5,q> 0)
n:你自己的 n 种技能
t:魔力恢复指环每秒钟可以帮助您恢复 t 点魔力值
q:boss 在你每次攻击后对你 q 点伤害,不耗时。
紧接着 n 行,各有 2 整数 ai 和 bi(0 < ai,bi < = 100)。表示使用当前这个技能花费你 ai
魔力值,对 boss 的生命值的伤害点数 bi。
最后的一行是 n = t =q= 0。
【输出文件】
每组测试数据输出一行:
一个整数 min,杀死 boss 的最少时间,如果玩家死了,输出“My god”(不含引号)。
【样例输入】
4 2 25
10 5
20 10
30 28
76 70
4 2 25
10 5
20 10
30 28
77 70
0 0 0
【样例输出】
4
My god
【提示】
当攻击的时候,同一时间,你只能选择一种攻击模式,技能或者是普通攻击,普通攻击
只能伤害 boss 一点生命值。
很明显的DP题,但是我考试的时候并没有写出,因为状态定义的太差,导致转移的时候有问题。
换了种状态定义,就很好DP了:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #define ll long long #define il inline #define db double #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) using namespace std; int a[145]; int b[145]; int f[145][145];//j次攻击,魔力为i时的最大伤害 il void work(int n,int t,int q) { if(!n&&!t&&!q) exit(0); memset(f,0,sizeof(f)); for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]); a[0]=0,b[0]=1; for(int k=1;k<=100;k++) for(int i=0;i<=n;i++) for(int j=100;j>=a[i];j--) { int now=j-a[i]+t; if(now>100) now=100; f[now][k]=max(f[now][k],f[j][k-1]+b[i]); if(f[now][k]>=100&&(k-1)*q<=100) { printf("%d\n",k); return; } } printf("My god\n"); } int main() { freopen("warcraft.in","r",stdin); freopen("warcraft.out","w",stdout); int n,t,q; while(scanf("%d%d%d",&n,&t,&q)!=EOF) work(n,t,q); return 0; }
以上是关于魔兽 DP的主要内容,如果未能解决你的问题,请参考以下文章
bzoj 1017[JSOI2008]魔兽地图DotR - 树形dp
[BZOJ1017][JSOI2008]魔兽地图DotR 树形dp