ZOJ 3769 Diablo III

来源:互联网 发布:人死犯冷退的算法 编辑:程序博客网 时间:2024/05/16 10:55

Diablo III

Time Limit: 2 Seconds      Memory Limit: 65536 KB

Diablo III is an action role-playing video game. A few days ago, Reaper of Souls (ROS), the new expansion of Diablo III, has been released! On hearing the news, the crazy video game nerdYuzhi shouted: "I'm so excited! I'm so excited! I wanna kill the Diablo once more!"

The ROS introduced a lot of new features and changes. For example, there are two new attributes for players in the game: Damage and Toughness. The attribute Damage indicates the amount of damage per second you can deal and the Toughness is the total amount of raw damage you can take.

To beat the Diablo, Yuzhi need to select the most suitable equipments for himself. A player can carry at most 13 equipments in 13 slots: Head, Shoulder, Neck, Torso, Hand, Wrist, Waist, Legs, Feet, Shield, Weapon and 2 Fingers. By the way, there is a special type of equipment: Two-Handed. A Two-Handed equipment will occupy both Weapon and Shield slots.

Each equipment has different properties on Damage and Toughness, such as a glove labeled "30 20" means that it can increase 30 Damage and 20 Toughness for the player who equips it in the Hand slot. The total Damage and Toughness is the sum of Damage and Toughness of all equipments on the body. A player without any equipments has 0 Damage and 0 Toughness.

Yuzhi has N equipments stored in his stash. To fight against the Diablo without lose the battle, he must have at leastM Toughness. In addition, he want to finish the battle as soon as possible. That means the Damage should be as much as possible. Please helpYuzhi to determine which equipments he should take.

Input

There are multiple test cases. The first line of input is an integer T indicates the number of test cases. For each test case:

The first line contains 2 integers N (1 <= N <= 300) andM (0 <= M <= 50000). The next N lines are the description of equipments. The i-th line contains a stringSi and two integers Di and Ti (1 <=Di, Ti <= 50000). Si is the type of equipment in {"Head", "Shoulder", "Neck", "Torso", "Hand", "Wrist", "Waist", "Legs", "Feet", "Finger", "Shield", "Weapon", "Two-Handed"}.Di and Ti are the Damage and Toughness of this equipment.

Output

For each test case, output the maximum Damage that Yuzhi can get, or -1 if he can not reach the required Toughness.

Sample Input

21 25Hand 30 205 25Weapon 15 5Shield 5 15Two-Handed 25 5Finger 5 10Finger 5 10

Sample Output

-135

Author: YU, Zhi; JIANG, Kai
Source: The 14th Zhejiang University Programming Contest

题意:给出13类装备,每种装备都有攻击力和防御值,每种装备只允许选择一个,求满足防御值至少在M的情况下,攻击力最大为多少.

有几个条件:13种装备里如果选择了双手装备,就不能选择武器和护盾了,还有戒指可以双手各带一个.

思路:首先不考虑条件,设dp[i][j]为前i种装备,防御值达到j的时候的最大攻击力.

那么可以有dp[i][j + t] = max(dp[i][j + t], dp[i - 1][j] + d)这里dp[i - 1][j]不等于-1,也就是必须先能达到这个防御值.

考虑双手装备的问题,可以把武器和护盾单独作为一件双手装备或者把两者合起来组合成一个双手装备,这样条件就没了.

考虑戒指的问题,选择单个戒指就相当于只有一只手戴戒指,把戒指两两组合起来也就相当于双手都带了戒指,所以条件就都没了.

不过这里的M比较大,直接从第一类装备开始递推可能会超时,由于种类之间没有关系所以从哪个种类开始递推都没有关系,所以这里可以把种类按照装备数量从大到小排序,把数量最大的种类作为递推起点,这里就可以省下很多时间


一开始总是T啊T……看有的人倒着dp就不会。。不知道为毛。。于是改成C风格还是过不了。。为啥非要倒着呢?今天才知道。。

应该是随机的数据正好搞的后面的数目比较多。。其实也不用排序了。。首先把数目最多的装备进行处理就行了。。然后STL乱搞都没问题的。。


也是比较无语的一道题。。。这样卡时间


#include<map>#include<string>#include<cstring>#include<cstdio>#include<cstdlib>#include<cmath>#include<queue>#include<vector>#include<iostream>#include<algorithm>#include<bitset>#include<climits>#include<list>#include<iomanip>#include<stack>#include<set>using namespace std;char equipment[20][20]={"Head", "Shoulder", "Neck", "Torso", "Hand", "Wrist", "Waist", "Legs", "Feet", "Finger", "Shield", "Weapon", "Two-Handed"};int seek(const char *s){for(int i=0;i<13;i++)if(strcmp(equipment[i],s)==0)return i;}struct Ppt{int d,t;}ppt[20][310*310];int len[20],dp[20][50010];int main(){int T;scanf("%d",&T);while(T--){int n,m;scanf("%d%d",&n,&m);memset(len,0,sizeof(len));while(n--){char s[20];int d,t;scanf("%s%d%d",s,&d,&t);int id=seek(s);ppt[id][len[id]].d=d;ppt[id][len[id]].t=t;len[id]++;}if(len[9]>1){for(int i=0;i<len[9];i++)for(int j=i+1;j<len[9];j++){ppt[13][len[13]].d=ppt[9][i].d+ppt[9][j].d;ppt[13][len[13]].t=ppt[9][i].t+ppt[9][j].t;len[13]++;}memcpy(ppt[9],ppt[13],len[13]*sizeof(Ppt));len[9]=len[13];}if(len[10]==0){memcpy(ppt[10],ppt[11],len[11]*sizeof(Ppt));memcpy(ppt[10]+len[11],ppt[12],len[12]*sizeof(Ppt));len[10]=len[11]+len[12];}else if(len[11]==0){memcpy(ppt[10]+len[10],ppt[12],len[12]*sizeof(Ppt));len[10]+=len[12];}else{for(int i=0;i<len[10];i++)for(int j=0;j<len[11];j++){ppt[12][len[12]].d=ppt[10][i].d+ppt[11][j].d;ppt[12][len[12]].t=ppt[10][i].t+ppt[11][j].t;len[12]++;}memcpy(ppt[10],ppt[12],len[12]*sizeof(Ppt));len[10]=len[12];}int index=0;for(int i=0;i<11;i++)if(len[i]>len[index])index=i;swap(ppt[0],ppt[index]);swap(len[0],len[index]);memset(dp,-1,sizeof(dp));for(int i=0;i<len[0];i++)dp[0][min(ppt[0][i].t,m)]=max(dp[0][min(ppt[0][i].t,m)],ppt[0][i].d);for(int i=1;i<11;i++){if(len[i]==0){memcpy(dp[i],dp[i-1],(m+1)*sizeof(int));continue;}int ii=i-1;if(ii>=0){dp[ii][0]=0;for(int j=0;j<=m;j++)if(dp[ii][j]!=-1)for(int k=0;k<len[i];k++){int t=min(j+ppt[i][k].t,m);dp[i][t]=max(dp[i][t],dp[ii][j]+ppt[i][k].d);}}}printf("%d\n",dp[10][m]);}}


0 0
原创粉丝点击