描述

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.

输入

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 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.

输出

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

样例输入

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

样例输出

-1
35

题意:给出13类装备,每种装备都有攻击力和防御值,每种装备只允许选择一个,13种装备里如果选择了双手装备,就不能选择武器和护盾了,还有戒指可以双手各带一个,求满足防御值至少在M的情况下,攻击力最大为多少。

解题思路:设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比较大,直接从第一类装备开始递推可能会超时,由于种类之间没有关系所以从哪个种类开始递推都没有关系,所以可以倒着来推,把数量较大的种类作为递推起点,可以省下很多时间。还有这里用一维可能会出问题,代码中当k=m=kk时可能会同类取了多个

转载自博客:https://blog.csdn.net/a664607530/article/details/70216835

#include <stdio.h>
#include <string>
#include <map>
#include <vector>
#include <iostream>
#define MAXN 310
using namespace std; int n,m;
map< string , int > M;
int max(int a, int b){
if(a>b)return a;
else return b;
}
void init(){
M["Head"]=;
M["Shoulder"]=;
M["Neck"]=;
M["Torso"]=;
M["Hand"]=;
M["Wrist"]=;
M["Waist"]=;
M["Legs"]=;
M["Feet"]=;
M["Shield"]=;//finger
M["Weapon"]=;
M["Finger"]=;
M["Two-Handed"]=;
}
struct Node
{
int d,t;
}nod;
vector<Node> V[];//存储同类物品
int dp[][];
int vd,vt;
void read(){
int i,j,d,t;
char ch[];
scanf("%d %d" ,&n ,&m);
for(i=; i<; i++){
V[i].clear();
}
for(i=; i<n; i++){
scanf("%s %d %d" ,ch , &d ,&t);
int index=M[string(ch)];
nod.d=d;
nod.t=t;
V[index].push_back( nod );
if(index== || index==){
V[].push_back( nod );
}
}
//两只手的装备
for(i=; i<V[].size(); i++){
for(j=; j<V[].size(); j++){
nod.d=V[][i].d+V[][j].d;
nod.t=V[][i].t+V[][j].t;
V[].push_back( nod );
}
}
//存戒指
V[].clear();
for(i=; i<V[].size(); i++){
V[].push_back( V[][i] );
for(j=i+; j<V[].size(); j++){
nod.d=V[][i].d+V[][j].d;
nod.t=V[][i].t+V[][j].t;
V[].push_back( nod );
}
}
V[].clear();
} int main(){
init();
int t;
int i,j,k;
scanf("%d" ,&t);
while( t-- ){
read();
memset(dp,-,sizeof(dp));
//12单独处理一下,存到9
dp[][]=;
for(i=; i<V[].size(); i++){
nod=V[][i];
if(nod.t>m){
vt=m;
}else{
vt=nod.t;
}
vd=nod.d;
dp[][vt]=max( dp[][vt] , vd );
}
for(k=; k>=; k--){
for(j=; j<=m; j++){
dp[k][j]=max( dp[k][j],dp[k+][j] );
if( dp[k+][j]==- )continue;
/*
dp[k][j] 表示k件装备,它所用的防御是j的伤害
当前装备伤害+之前伤害最大值
dp[k][vt]=max( dp[k][vt], nod.d+dp[k+1][j] )
*/
for(i=; i<V[k].size(); i++){
nod=V[k][i];
if( nod.t +j > m ){
vt=m;
}else{
vt=nod.t +j;
}
dp[k][vt]=max( dp[k][vt], nod.d+dp[k+][j] );
}
}
}
printf("%d\n" ,dp[][m]);
}
return ;
}

ZOJ 3769-Diablo III(DP)的更多相关文章

  1. ZOJ 3769 Diablo III(分组背包)

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3769 题意:有13种装备,每种装备值可以穿戴一种,特殊的就是双手武器和单手 ...

  2. ZOJ 4027 Sequence Swapping(DP)题解

    题意:一串括号,每个括号代表一个值,当有相邻括号组成()时,可以交换他们两个并得到他们值的乘积,问你最大能得到多少 思路:DP题,注定想得掉头发. 显然一个左括号( 的最远交换距离由他右边的左括号的最 ...

  3. ZOJ 3769 Diablo III

    描述 Diablo III is an action role-playing video game. A few days ago, Reaper of Souls (ROS), the new e ...

  4. ZOJ 2625 Rearrange Them(DP)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1625 题目大意:将n个数重新排列,使得每个数的前一个数都不能和之前的 ...

  5. ZOJ 2745 01-K Code(DP)(转)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1745 题目大意:一个串由N个字符组成,每个字符是‘0’或者是‘1’, ...

  6. ZOJ 1013 Great Equipment(DP)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=13 题目大意:说的是有三种不同的装备,分别是头盔,盔甲,战靴需要运输, ...

  7. LightOJ1017 Brush (III)(DP)

    题目大概说一个平面上分布n个灰尘,现在要用一个宽w的刷子清理灰尘:选择一个起点,往水平线上扫过去这个水平线上的灰尘就消失了.问最多进行k次这样的操作能清理最多多少灰尘. 没什么的DP. 先按垂直坐标给 ...

  8. ZOJ 3211 Dream City(DP)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3374 题目大意:JAVAMAN 到梦幻城市旅游见到了黄金树,黄金树上 ...

  9. ZOJ 2702 Unrhymable Rhymes(DP)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1702 题目大意:给定有很多数字组成的诗,譬如 “AABB”, “AB ...

随机推荐

  1. 姿势摆好,一招学会android的布局优化!

    作为android应用来讲,无论应用本身多么美观,功能多么强大,内容多么丰富.但如果App本身打开界面缓慢超过手机16ms刷新一次页面的时间,就会产生卡顿.用户体验都会变得极差,导致用户量减少.所以我 ...

  2. kindEditor 富文本编辑器 使用介绍

    第一版:存放位置:  ---->把该创建的文件包放到javaWeb 过程的 WEB_INF 下:如图所示. 第二步:< kindEditor 插件的引用> :JS引用 <scr ...

  3. django模板 内建标签

    autoescape 控制当前自动转义的行为,有on和off两个选项 {% autoescape on %} {{ body }} {% endautoescape %} block 定义一个子模板可 ...

  4. python并发编程之多线程2------------死锁与递归锁,信号量等

    一.死锁现象与递归锁 进程也是有死锁的 所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用, 它们都将无法推进下去.此时称系统处于死锁状态或系统 ...

  5. Let the Balloon Rise <map>的应用

    Contest time again! How excited it is to see balloons floating around. But to tell you a secret, the ...

  6. Java基础之多线程框架

    一.进程与线程的区别 1.定义: 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比 ...

  7. 第二周学习总结-Java

    2018年7月22日 暑假第二周马上就要结束了,这一周我继续学习了java. 本周学到了一些Java的修饰词,比如static.private.public等,这些修饰词用法与c++类似,很容易掌握. ...

  8. C++ GetComputerName()

    关于函数“GetComputerName()”,参考:https://msdn.microsoft.com/en-us/library/windows/desktop/ms724295(v=vs.85 ...

  9. python之ORM操作

    1. SQLalchemy简介 SQLAlchemy是一个开源的SQL工具包,基本Python编程语言的MIT许可证而发布的对象关系映射器.SQLAlchemy提供了“一个熟知的企业级全套持久性模式, ...

  10. 读C#开发实战1200例子记录-2017年8月14日10:03:55

    C# 语言基础应用,注释 "///"标记不仅仅可以为代码段添加说明,它还有一项更重要的工作,就是用于生成自动文档.自动文档一般用于描述项目,是项目更加清晰直观.在VisualStu ...