[dp] zoj 3769 Diablo III

题目链接:

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3769

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 nerd Yuzhi 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 least M Toughness. In addition, he want
to finish the battle as soon as possible. That means the Damage should be as much as possible. Please help Yuzhi 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) and M (0 <= M <= 50000). The next N lines are the description of equipments.
The i-th line contains a string Si and two integersDi and Ti (1 <= DiTi <= 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

2
1 25
Hand 30 20
5 25
Weapon 15 5
Shield 5 15
Two-Handed 25 5
Finger 5 10
Finger 5 10

Sample Output

-1
35

Author: YU, Zhi; JIANG, Kai

Source: The 14th Zhejiang University Programming Contest

Submit    Status

题目意思:

有13种装备,每种装备只能选一个,每种装备有一个伤害值和防御值,其中如果选Two-Handed的话就不能选Shield和Weapon,Finger可以选两个。求怎样选择,使得在防御值达到m的情况,伤害总值最大。

解题思路:

转化为背包。

这题是有限制的背包,但是如果把条件转化,就是个背包问题了。

可以把Shield和Weapon放到Two-Handed中,这样就满足Weapon、Shield和Two-Handed只会选一种,注意要把Shield+Weapon也当成一个。

Finger的话,可以枚举所有的两个再添加成一个。

注意本题不能只开一维,因为是要求不小于m的,只能枚举前面已经确定的防御值情况,去更新后面的情况。>m的状态记为m.

这题卡常数,要把各种的个数按大到小排个序,先把个数最多的那种先处理出来,不然会超时(当然如果不排序的话,从后往前推,也不会超时,估计是数据的原因)。

代码:

//#include<CSpreadSheet.h>

#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#include<cmath>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

map<string,int>myp;

#define Maxn 330

void init()
{
    myp["Head"]=1,myp["Shoulder"]=2,myp["Neck"]=3,myp["Torso"]=4;
    myp["Hand"]=5,myp["Wrist"]=6,myp["Waist"]=7,myp["Legs"]=8;
    myp["Feet"]=9,myp["Shield"]=10,myp["Weapon"]=11,myp["Finger"]=12;
    myp["Two-Handed"]=13;

}
struct PP
{
    int da,to;
}pp;
int n,m;
int dp[15][55000];
vector<PP>myv[15];

int Max(int a,int b)
{
    return a>b?a:b;
}

bool cmp(vector<PP> a,vector<PP> b)
{
    return a.size()>b.size();
}

int main()
{
   //freopen("in.txt","r",stdin);
   //freopen("out.txt","w",stdout);
   //printf("%d\n",1<<14); //16384
   init();

   int t;

   scanf("%d",&t);
   while(t--)
   {
       scanf("%d%d",&n,&m);

       for(int i=1;i<=13;i++)
            myv[i].clear();

       for(int i=1;i<=n;i++)
       {
           string a;
           cin>>a>>pp.da>>pp.to;
           int in=myp[a];

            myv[in].push_back(pp);
            if(in==10||in==11)  //把shield和weapon都放到Two-Handed
                myv[13].push_back(pp);

       }
       //处理选择10+11的情况
       for(int i=0;i<myv[10].size();i++)
       {
           for(int j=0;j<myv[11].size();j++)
           {
               PP temp;
               pp.da=myv[10][i].da+myv[11][j].da;
               pp.to=myv[10][i].to+myv[11][j].to;

               myv[13].push_back(pp);
           }
       }
       //处理Fingers的情况 把任意的两个Fingers都枚举出来
       myv[10].clear();
       for(int i=0;i<myv[12].size();i++)
       {
           myv[10].push_back(myv[12][i]);
           for(int j=i+1;j<myv[12].size();j++)
           {
               PP temp;
               temp.da=myv[12][i].da+myv[12][j].da;
               temp.to=myv[12][i].to+myv[12][j].to;
               myv[10].push_back(temp);
           }
       }
       myv[11].clear();
       myv[11]=myv[13];
       sort(myv+1,myv+12,cmp);

       memset(dp,-1,sizeof(dp));
       dp[1][0]=0;

       for(int i=0;i<myv[1].size();i++)
       {
           int lim;
           if(myv[1][i].to>=m)
                lim=m;
           else
                lim=myv[1][i].to;
           dp[1][lim]=max(dp[1][lim],myv[1][i].da);
       }

       for(int i=2;i<=11;i++)
       {
           int sum=myv[i].size();
           for(int j=0;j<=m;j++)
           {

               if(dp[i-1][j]==-1)
                    continue;
               dp[i][j]=max(dp[i][j],dp[i-1][j]); //可以不选

               for(int k=0;k<sum;k++)
               {
                   int lim;

                   if(j+myv[i][k].to>=m)
                        lim=m;
                   else
                        lim=j+myv[i][k].to;

                   dp[i][lim]=Max(dp[i][lim],dp[i-1][j]+myv[i][k].da);

               }
           }
       }
       printf("%d\n",dp[11][m]);

   }
   return 0;
}

[dp] zoj 3769 Diablo III,布布扣,bubuko.com

时间: 2024-10-28 10:42:03

[dp] zoj 3769 Diablo III的相关文章

ZOJ 3769 Diablo III(分组背包)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3769 题意:有13种装备,每种装备值可以穿戴一种,特殊的就是双手武器和单手武器,双手武器和单手武器+盾只能选择一种,戒指可以双手各戴一个.每个装备都有一个攻击值和防御值,现在要在防御值至少到达m的情况下可以达到的最大攻击力. 思路:分组背包题目. 把单手武器和盾组合起来放到双手武器当中,戒指也需要两两组合. 接下来就是一个分组背包了,比较重要的是这道题目需要开二维数组,因

2014 Super Training #7 C Diablo III --背包问题(DP)

原题: ZOJ 3769 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3769 一个带有一些限制的背包问题. 假设在没有限制的情况下,那么定义:dp[i][j]表示在前 i 类物品中,总的Toughness为 j 的时候最大的伤害值. 取到第K类的第x个物品时(属性值为D,T),则有转移方程: dp[K][j+T] = max(dp[K][j+T],dp[K-1][j]+D) .其中j+T超过m时按m算就可以了. 但是

[dp] zoj 3740 Water Level

题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5122 Water Level Time Limit: 2 Seconds      Memory Limit: 65536 KB Hangzhou is a beautiful city, especially the West Lake. Recently, the water level of the West Lake got lower and lower

[递推dp] zoj 3747 Attack on Titans

题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5170 Attack on Titans Time Limit: 2 Seconds      Memory Limit: 65536 KB Over centuries ago, mankind faced a new enemy, the Titans. The difference of power between mankind and their newf

[dp] zoj 3682 E - Cup 3

题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3682 E - Cup 3 Time Limit: 3 Seconds      Memory Limit: 65536 KB The 2012 Europe Cup was over and Spain won the Championship. The fans of Spain want to hold some activities to celebra

概率dp ZOJ 3640

Help Me Escape Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Status Practice ZOJ 3640 Appoint description:  System Crawler  (2014-10-22) Description Background     If thou doest well, shalt thou not be accepted? an

(状态压缩DP) zoj 3471

T - Most Powerful Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Submit Status Practice ZOJ 3471 Appoint description:  System Crawler  (2015-04-16) Description Recently, researchers on Mars have discovered N powerful atoms

状压DP [ZOJ 3471] Most Powerful

Most Powerful Time Limit: 2 Seconds      Memory Limit: 65536 KB Recently, researchers on Mars have discovered N powerful atoms. All of them are different. These atoms have some properties. When two of these atoms collide, one of them disappears and a

DP ZOJ 3872 Beauty of Array

题目传送门 1 /* 2 DP:dp 表示当前输入的x前的包含x的子序列的和, 3 求和方法是找到之前出现x的位置(a[x])的区间内的子序列: 4 sum 表示当前输入x前的所有和: 5 a[x] 表示id: 6 详细解释:http://blog.csdn.net/u013050857/article/details/45285515 7 */ 8 #include <cstdio> 9 #include <algorithm> 10 #include <cmath>