ZOJ 3769 —— Diablo III(背包,DP)
2014-04-06 21:43
471 查看
题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3769
额,题目有点长的样子。
大概意思就是说人身上有13个地方可以装备道具,其中两个注意点,一个是fingers,这说明有两根手指可以装备。。。另一个是Two-Handed这种装备会同时占据Weapon和Shield两种道具的装备位置,同一位置只能装备一个道具,不同位置不会影响。
每种道具都会有damage和toughness两个参数,题目要问的是,从中选出一些装备,那么人物的damage值和toughness就是所选装备对应的和,在保证toughness不小于m的情况下,求最大的damage,如果无法达到toughness,就输出-1。
这个背景还是挺经典的背包问题,只是套上一些限制。
如果按照装备的类型分类,最多就13类,先不管前面说的两个注意点,如果这13类之间是没有影响的,dp[i][j]来表示取到第i 类物品,总toughness是j 时候,最优伤害值。
那么对于第i 类物品,假设当前考虑到其中的第k件物品,两个参数分别是d和t,那么枚举前一类物品能够达到的所有状态dp[i-1][j],可以推出新的状态dp[i][j+t] = max(dp[i][j+t], dp[i][j]+d)
而在这个问题中,因为我们只需要达到m,所以对于j+t超过m情况,可以简单记录为m。
然后建立在这种思路的基础上,我们再来考虑那两个条件:
1、对于两个手指的,无论是只装备一根手指,还是装备了两只,都用手指这一类来表示,那么,所有手指装备本身当作只装备一根手指,装备两只的你就两两枚举下吧;
2、对于Weapon和Shield两种道具以及Two-Handed,我们还是把它们当成一种来处理,首先各自肯定当成一件物品,然后就是枚举Weapon和Shield的搭配了;
这样处理之后,按照我们的递推式,同类物品之间是不会有冲突的,所以以上处理过后,题目的限制条件就不见了。。。
然后我们就可以快乐地AC了~~
PS:因为扫物品名称列表的时候,几个特殊处理的物品都是在后面,所以具体到实现的时候,我是从后往前推的。。。
额,题目有点长的样子。
大概意思就是说人身上有13个地方可以装备道具,其中两个注意点,一个是fingers,这说明有两根手指可以装备。。。另一个是Two-Handed这种装备会同时占据Weapon和Shield两种道具的装备位置,同一位置只能装备一个道具,不同位置不会影响。
每种道具都会有damage和toughness两个参数,题目要问的是,从中选出一些装备,那么人物的damage值和toughness就是所选装备对应的和,在保证toughness不小于m的情况下,求最大的damage,如果无法达到toughness,就输出-1。
这个背景还是挺经典的背包问题,只是套上一些限制。
如果按照装备的类型分类,最多就13类,先不管前面说的两个注意点,如果这13类之间是没有影响的,dp[i][j]来表示取到第i 类物品,总toughness是j 时候,最优伤害值。
那么对于第i 类物品,假设当前考虑到其中的第k件物品,两个参数分别是d和t,那么枚举前一类物品能够达到的所有状态dp[i-1][j],可以推出新的状态dp[i][j+t] = max(dp[i][j+t], dp[i][j]+d)
而在这个问题中,因为我们只需要达到m,所以对于j+t超过m情况,可以简单记录为m。
然后建立在这种思路的基础上,我们再来考虑那两个条件:
1、对于两个手指的,无论是只装备一根手指,还是装备了两只,都用手指这一类来表示,那么,所有手指装备本身当作只装备一根手指,装备两只的你就两两枚举下吧;
2、对于Weapon和Shield两种道具以及Two-Handed,我们还是把它们当成一种来处理,首先各自肯定当成一件物品,然后就是枚举Weapon和Shield的搭配了;
这样处理之后,按照我们的递推式,同类物品之间是不会有冲突的,所以以上处理过后,题目的限制条件就不见了。。。
然后我们就可以快乐地AC了~~
PS:因为扫物品名称列表的时候,几个特殊处理的物品都是在后面,所以具体到实现的时候,我是从后往前推的。。。
#include<cstdio> #include<cstring> #include<vector> #include<algorithm> using namespace std; #define pb push_back char name[20][20]={"Head","Shoulder","Neck","Torso","Hand","Wrist","Waist","Legs","Feet","Finger","Shield","Weapon","Two-Handed"}; int t, n, m; struct Goods{ int dmg, tou; }g; int getnum(char* s){ for(int i=0; i<13; i++) if(strcmp(s, name[i])==0) return i; } vector<Goods> V[13];//用vector来存储同类物品 int dp[13][50001], vd, vt; int main(){ int i, j, k; char s[20]; scanf("%d", &t); while(t--){ scanf("%d %d", &n, &m); for(i=0; i<13; i++) V[i].clear(); while(n--){ scanf("%s %d %d", s, &i, &j); k = getnum(s); V[k].pb((Goods){i,j}); if(k==11 || k==10){//如果发现Weapon和Shield的,也算到Two-Handed里面去 V[12].pb((Goods){i,j}); } } //枚举Weapon和Shield两两组合 for(i=0; i<V[11].size(); i++){ for(j=0; j<V[10].size(); j++){ V[12].pb((Goods){V[11][i].dmg+V[10][j].dmg, V[11][i].tou+V[10][j].tou}); } } //把存放Shield的清空,用来记录finger的物品,Weapon的清不清空无所谓 V[10].clear(); for(i=0; i<V[9].size(); i++){ V[10].pb(V[9][i]); //枚举finger物品的两两组合 for(j=i+1; j<V[9].size(); j++){ V[10].pb((Goods){V[9][i].dmg+V[9][j].dmg, V[9][i].tou+V[9][j].tou}); } } V[9].clear();//这个清空,因为finger的情况都存到V[10]里面去了 memset(dp,-1,sizeof(dp)); dp[11][0]=0; for(i=0; i<V[12].size(); i++){ g = V[12][i]; vt = g.tou>m?m:g.tou; vd = g.dmg; dp[11][vt] = max(dp[11][vt], vd); } for(k=10; k>=0; k--){ for(j=0; j<=m; j++){ dp[k][j] = max(dp[k][j], dp[k+1][j]); if(dp[k+1][j]==-1) continue; for(i=0; i<V[k].size(); i++){ g = V[k][i]; vt = (g.tou+j)>m?m:(g.tou+j); vd = g.dmg+dp[k+1][j]; dp[k][vt] = max(dp[k][vt], vd); } } } printf("%d\n", dp[0][m]); } return 0; }
相关文章推荐
- ZOJ - 3769 - Diablo III (分组背包 ,dp)
- 2014 Super Training #7 C Diablo III --背包问题(DP)
- ZOJ 2972-Hurdles of 110m(背包dp)
- [ZOJ 3682] E - Cup 3 (背包DP计数 + 滚动数组)
- ZOJ 3769 Diablo III(DP)
- ZOJ 3769 Diablo III(分组背包)
- zoj 3268 Treasure Hunt III (dp)
- ZOJ 3682 简单dp 背包
- hdu 1028/哈理工OJ2004 Ignatius and the Princess III【完全背包】【dp】
- HDU-1028 Ignatius and the Princess III(DP[完全背包]||生成函数)
- ZOJ 3703 Happy Programming Contest 0-1背包 DP
- ZOJ 4772 Treasure Hunt I 树形DP(背包) && hdu The Ghost Blows Light 树形DP(背包)
- ZOJ 3769 (分组背包)
- zoj 2972 Hurdles of 110m(dp,背包)
- HDU1028——Ignatius and the Princess III(背包问题dp)
- zoj 3201 Tree of Tree(树形背包dp)
- ZOJ-3264 Present for MM (背包dp)
- ZOJ 3626 —— Treasure Hunt I(树形DP + 背包)
- ZOJ3769-Diablo III(分组背包)
- ZOJ 3812 We Need Medicine(dp、背包、状态压缩、路径记录)