HDOJ 6508 Problem I. Spell Boost (01背包/DP)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6508
题目:
You have n cards, each with two attributes wi and xi. If you use card i, you will cost wi points of power and cause xi damage to the enemy.
Among them, there are two special types of cards: some cards are magic cards and some have “spell boost effect”. Everytime you have used a magic card, for each unused “spell boost effect” card i: if the the current cost of i (i.e. wi) is positive, then wi will be reduced by 1. Note that some cards may be both
magic cards and have spell boost effect.
Now you have W points of power, you need to calculate maximum total damage you can cause.
n W
w1 x1 is_magic1 is_spell_boost1
w2 x2 is_magic2 is_spell_boost2
...
...
...
wn xn is_magicn is_spell_boostn
1 ≤ n ≤ 500
0 ≤ W, wi, xi ≤ 500, and all of them are integers.
is_magici means: If this card is magic card, the value is 1, otherwise the value is 0.
is_spell_boosti means: If this card has spell boost effect, the value is 1, otherwise 0
题意:
给出四种卡片 既是魔法卡也是增幅卡 是魔法卡不是增幅卡 是增幅卡不是魔法卡 不是增幅卡也不是魔法卡
每一张卡片都包含两个值 打出牌的代价 和打出牌的价值
其中魔法卡的作用是使所有未使用的增幅卡代价减1 如果代价已经为0就不减了
思路:
从增幅卡和魔法卡的作用中可以看出来 打出这四种牌是有先后顺序的 增幅卡要尽可能后打出 魔法卡要尽可能先打出
我采用的顺序是 是魔法卡不是增幅卡>是增幅卡不是魔法卡>既是魔法卡也是增幅卡>不是增幅卡也不是魔法卡
然后采用三维dp来转移 dp[i][j][k]表示的是当前已经打出的伤害和 i表示当前已经打到的第i张牌 j表示当前已经打出的增幅卡的数量 k表示当前已经用掉的代价和
直接用三维去存储的话存不下 采用了滚动数组去滚掉第一维i(当前的位置只依赖上一位 可以采用滚动数组只记录两个值 i%2和(i-1)%2)
代码:
#include <bits/stdc++.h> using namespace std;
const int maxn=;
int n,W;
int dp[][maxn][maxn]; struct node{
int w,x,vis1,vis2;
}kk[maxn]; int cmp(node a,node b){
if(a.vis1!=b.vis1) return a.vis1>b.vis1;
if(a.vis2!=b.vis2) return a.vis2<b.vis2;
return a.w<b.w;
} int main(){
// freopen("1.in","r",stdin);
while(~scanf("%d%d",&n,&W)){
for(int i=;i<=n;i++){
scanf("%d%d%d%d",&kk[i].w,&kk[i].x,&kk[i].vis1,&kk[i].vis2);
}
sort(kk+,kk++n,cmp);
memset(dp[],-,sizeof(dp[]));
dp[][][]=;
// cout<<n<<endl;
for(int i=;i<=n;i++){
memset(dp[i%],-,sizeof(dp[i%]));
for(int j=;j<=i;j++){
for(int k=;k<=W;k++){
// if(dp[(i-1)%2][j][k]==-1) continue;
dp[i%][j][k]=dp[(i-)%][j][k];
if(kk[i].vis1== && kk[i].vis2== && j->= && k-max(kk[i].w-(j-),)>= && dp[(i-)%][j-][k-max(kk[i].w-(j-),)]!=-)
dp[i%][j][k]=max(dp[i%][j][k],dp[(i-)%][j-][k-max(kk[i].w-(j-),)]+kk[i].x); //既是魔法卡也是增幅卡
if(kk[i].vis1== && kk[i].vis2== && k-max(kk[i].w-j,)>= && dp[(i-)%][j][k-max(kk[i].w-j,)]!=-)
dp[i%][j][k]=max(dp[i%][j][k],dp[(i-)%][j][k-max(kk[i].w-j,)]+kk[i].x); //只是增幅卡
if(kk[i].vis1== && kk[i].vis2== && j->= && k-kk[i].w>= && dp[(i-)%][j-][k-kk[i].w]!=-)
dp[i%][j][k]=max(dp[i%][j][k],dp[(i-)%][j-][k-kk[i].w]+kk[i].x); //只是魔法卡
if(kk[i].vis1== && kk[i].vis2== && k-kk[i].w>= && dp[(i-)%][j][k-kk[i].w]!=-)
dp[i%][j][k]=max(dp[i%][j][k],dp[(i-)%][j][k-kk[i].w]+kk[i].x); //什么都不是
}
}
}
int ans=;
for(int i=;i<=n;i++){
for(int j=;j<=W;j++){
ans=max(ans,dp[n%][i][j]);
}
}
printf("%d\n",ans);
}
return ;
}
HDOJ 6508 Problem I. Spell Boost (01背包/DP)的更多相关文章
- noj [1479] How many (01背包||DP||DFS)
http://ac.nbutoj.com/Problem/view.xhtml?id=1479 [1479] How many 时间限制: 1000 ms 内存限制: 65535 K 问题描述 The ...
- PAT L3-001 凑零钱(01背包dp记录路径)
韩梅梅喜欢满宇宙到处逛街.现在她逛到了一家火星店里,发现这家店有个特别的规矩:你可以用任何星球的硬币付钱,但是绝不找零,当然也不能欠债.韩梅梅手边有104枚来自各个星球的硬币,需要请你帮她盘算一下,是 ...
- HDOJ 1203 I NEED A OFFER!(01背包)
10397507 2014-03-25 23:30:21 Accepted 1203 0MS 480K 428 B C++ 泽泽 题目链接:http://acm.hdu.edu.cn/showprob ...
- 饭卡------HDOJ杭电2546(还是01背包!!!!!!)
Problem Description 电子科大本部食堂的饭卡有一种非常诡异的设计,即在购买之前推断剩余金额. 假设购买一个商品之前,卡上的剩余金额大于或等于5元,就一定能够购买成功(即使购买后卡上剩 ...
- HDU 1203 I NEED A OFFER!(01 背包DP)
点我看题目 题意 : 中文题不详述. 思路 :类似于01背包的DP,就是放与不放的问题,不过这个要求概率,至少得到一份offer的反面就是一份也得不到,所以先求一份也得不到的概率,用1减掉就可以得到所 ...
- (01背包 dp)P1049 装箱问题 洛谷
题目描述 有一个箱子容量为VV(正整数,0≤V≤20000),同时有nn个物品(0<n≤30,每个物品有一个体积(正整数). 要求nn个物品中,任取若干个装入箱内,使箱子的剩余空间为最小. 输入 ...
- 0-1背包dp|波动数列|2014年蓝桥杯A组10-fishers
标题:波动数列 观察这个数列: 1 3 0 2 -1 1 -2 ... 这个数列中后一项总是比前一项增加2或者减少3. 栋栋对这种数列很好奇,他想知道长度为 n 和为 s 而且后一项总是比前一项增加a ...
- HDU 2602 Bone Collector (01背包DP)
题意:给定一个体积,和一些物品的价值和体积,问你最大的价值. 析:最基础的01背包,dp[i] 表示体积 i 时最大价值. 代码如下: #pragma comment(linker, "/S ...
- Bookshelf 2(poj3628,01背包,dp递推)
题目链接:Bookshelf 2(点击进入) 题目解读: 给n头牛,给出每个牛的高度h[i],给出一个书架的高度b(所有牛的高度相加>书架高度b),现在把一些牛叠起来(每头牛只能用一次,但不同的 ...
随机推荐
- node-portfinder
nstallation $ [sudo] npm install portfinder Usage var portfinder = require('portfinder'); portfi ...
- [Alpha阶段]第九次Scrum Meeting
Scrum Meeting博客目录 [Alpha阶段]第九次Scrum Meeting 基本信息 名称 时间 地点 时长 第九次Scrum Meeting 19/04/14 大运村寝室6楼 30min ...
- ArrayBlockingQueue源码分析
ArrayBlockingQueue是一个基于数组实现的有界的阻塞队列. 属性 //底层存储元素的数组.为final说明一旦初始化,容量不可变,所以是有界的. final Object[] items ...
- Android中自定义IP控件
最近在搞Android项目,之前并没有系统的去学过这方面的编程,只能边看书边撸代码.在项目的开发的过程中,需要一个IP控件,后面了解到Android中并没有这样的控件,于是网上搜索,发现得到的结果并不 ...
- Git——开启区分大小写
前言 默认情况下git是忽略区分大小写的,多人合作的情况下不规范很容易造成问题,所以开启区分大小写. 步骤 开启 全局开启 git config --global core.ignorecase fa ...
- git只追踪特定类型的文件
比如我只关心所有office文档并排除掉~开头的辅助文件: * !*/ !*.docx !*.doc !*.xlsx ~*
- react native 封装TextInput组件
上一篇 react-native文章提到了TextInput组件对安卓的适配问题,因此对该组件进行封装很有必要. 文章地址 react native定报预披项目知识点总结 TextInput介绍 官 ...
- [模板]fhqTreap
用途 平衡树(可实现区间翻转) 原理 和treap一样,中序遍历表示权值的顺序,并且每个点有一个随机的附加值,形成一个堆来保证复杂度 但是不旋转,所有操作通过split和merge实现 分为两种spl ...
- Nginx-动态添加模块
Nginx动态添加模块 平滑升级 已经安装好的Nginx动态添加模块 说明: 已经安装好的Nginx,需要添加一个未被编译安装的模块,需要怎么弄呢? 这里已安装第三方nginx-rtmp-module ...
- CF1153D Pigeon d'Or
Description 给一棵树,每个点是子节点的最大值或最小值,将叶子节点填上整数,使这棵树的根最大. Solution 明显的\(dp\)题,代码很短. 分类讨论如下: 1.如果是叶子节点,\(d ...