Aizu 2155 Magic Slayer 背包DP
这是上上次对抗赛的题目了
其实现在发现整个代码从头到尾,都是用了背包,怪我们背包没深入学好。
比赛的时候,聪哥提出的一种思路是,预处理一下,背包出 ALL攻击 和 single攻击的 血量对应的最小花费,其实这些都没什么问题。。。主要是后面的问题,后面为了找到如何使用ALL攻击是最好的,我们是这样处理的,对怪物血量 升序排序,然后枚举,从哪个点开始,该点前面的怪物都用ALL杀死,后面的怪物都用single杀死,因为血高的放在后面多承受几次ALL攻击应该是最优的,这样看起来好像是对的。。也过了样例,就是WA了。。。。其实WA的很明显,我们居然三个人都没想到,刚刚重新敲这道题才发现这个策略大错特错了,我们这样枚举,很明显,没有计算,用了ALL攻击,但是没有杀死怪物的情况,也许这些就是最优解。。我们的策略,要么就不用ALL攻击,用了ALL攻击就一定要把怪物杀死。。。肯定有问题啊。
后来还是参考的别人的比较好的思路,前面的处理是一样的,不过换了一下,背包出 两种攻击 的 花费 对应的 最大攻击,即 下标是 花费,值是攻击力,这样便于后面的处理。
背包完之后,从0开始往上枚举 出 使用ALL的花费情况,然后就得到ALL的攻击总量,再遍历一遍怪物,就可以得到剩余血量用single攻击的花费,全部加起来就是可能的结果,全部枚举完就能求出最优解
刚刚还和聪哥讨论了好久,为什么枚举ALL花费情况就可以得到所有合理的ALL攻击组合,这其实就是利用了背包的特性,即,我给你一个上限,就能帮我求出这个上限中的最优组合,就是利用了背包的特性。。。所以我为什么说这整个题目就是一个背包题,全部都在利用背包的特性。。怪我没有对背包理解透彻,这种隐藏的可以枚举花费,通过背包得到组合情况没有想到。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 110010
using namespace std;
int hp[]; struct weapon{
int c,p;
}all[],sig[];
int dp[][N];
int all_num,sig_num;
int m,n;
void init()
{
all_num=sig_num=;
}
void proc()
{
memset(dp,,sizeof dp);
for (int i=;i<all_num;i++){
for (int j=all[i].c;j<N;j++){
dp[][j]=max(dp[][j],dp[][j-all[i].c]+all[i].p);
}
}
for (int i=;i<sig_num;i++){
for (int j=sig[i].c;j<N;j++){
dp[][j]=max(dp[][j],dp[][j-sig[i].c]+sig[i].p);
}
}
}
int bs(int val)
{
int l=,r=N-,mid;
while (l<r)
{
mid=(l+r)>>;
if (dp[][mid]<val) l=mid+;
else r=mid;
}
return l; }
int main()
{
char ch[],cc[];
int a,b;
while (scanf("%d",&n)){
if (!n) break;
init();
for (int i=;i<n;i++) scanf("%d",&hp[i]);
scanf("%d",&m);
bool flag=false;
for (int i=;i<m;i++){
scanf("%s %d %s %d",ch,&a,cc,&b);
// cout<<a<<" "<<b<<endl;
if (cc[]=='A') all[all_num++]=(weapon){a,b};
if (cc[]=='S') sig[sig_num++]=(weapon){a,b};
if (a== && b>) flag=;
}
if (flag) {puts("");continue;}
proc();
int ans=N*;
for (int i=;i<ans;i++){
int temp=i;
for (int j=;j<n;j++){
temp+=bs(hp[j]-dp[][i]);
}
ans=min(ans,temp);
}
printf("%d\n",ans);
}
return ;
}
Aizu 2155 Magic Slayer 背包DP的更多相关文章
- HDU 5119 Happy Matt Friends (背包DP + 滚动数组)
题目链接:HDU 5119 Problem Description Matt has N friends. They are playing a game together. Each of Matt ...
- Codeforces 922 E Birds (背包dp)被define坑了的一题
网页链接:点击打开链接 Apart from plush toys, Imp is a huge fan of little yellow birds! To summon birds, Imp ne ...
- 背包dp整理
01背包 动态规划是一种高效的算法.在数学和计算机科学中,是一种将复杂问题的分成多个简单的小问题思想 ---- 分而治之.因此我们使用动态规划的时候,原问题必须是重叠的子问题.运用动态规划设计的算法比 ...
- hdu 5534 Partial Tree 背包DP
Partial Tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid= ...
- HDU 5501 The Highest Mark 背包dp
The Highest Mark Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?p ...
- Codeforces Codeforces Round #319 (Div. 2) B. Modulo Sum 背包dp
B. Modulo Sum Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/577/problem/ ...
- noj [1479] How many (01背包||DP||DFS)
http://ac.nbutoj.com/Problem/view.xhtml?id=1479 [1479] How many 时间限制: 1000 ms 内存限制: 65535 K 问题描述 The ...
- HDU 1011 树形背包(DP) Starship Troopers
题目链接: HDU 1011 树形背包(DP) Starship Troopers 题意: 地图中有一些房间, 每个房间有一定的bugs和得到brains的可能性值, 一个人带领m支军队从入口(房 ...
- BZOJ 1004: [HNOI2008]Cards( 置换群 + burnside引理 + 背包dp + 乘法逆元 )
题意保证了是一个置换群. 根据burnside引理, 答案为Σc(f) / (M+1). c(f)表示置换f的不动点数, 而题目限制了颜色的数量, 所以还得满足题目, 用背包dp来计算.dp(x,i, ...
随机推荐
- redis5.5官方文档
https://www.cnblogs.com/zsl-find/articles/11780974.html 博客 https://redis.io/topics/cluster-tutorial ...
- js左右选项移动
<!--网页代码--><div class="modal" id="modal-primary7"> <div class=&qu ...
- firewalld学习-zone
原文地址:http://www.excelib.com/article/290/show firewalld默认提供了九个zone配置文件: block.xml.dmz.xml.drop.xml.ex ...
- Redis原理详解
Redis原理详解 数据类型 Redis最为常用的数据类型主要有以下五种: String Hash List Set Sorted set 在具体描述这几种数据类型之前,我们先通过一张图了解下Redi ...
- Typescript 实战 --- (9)ES6与CommonJS的模块系统
1.ES6模块系统 1-1.export 导出 (1).单独导出 // a.ts export let a = 1; (2).批量导出 // a.ts let b = 2; let c = 3; ex ...
- 011、MySQL取14天前Unix时间戳
#取14天前时间戳 SELECT unix_timestamp( DATE_SUB( curdate( ), INTERVAL DAY ) ); 效果如下: 不忘初心,如果您认为这篇文章有价值,认同作 ...
- setTimeout的异步
http://www.cnblogs.com/littledu/articles/2607211.html http://www.cnblogs.com/rubylouvre/archive/2009 ...
- Java 文件
章节 Java 基础 Java 简介 Java 环境搭建 Java 基本语法 Java 注释 Java 变量 Java 数据类型 Java 字符串 Java 类型转换 Java 运算符 Java 字符 ...
- C语言中可变参数的原理——printf()函数
函数原型: int printf(const char *format[,argument]...) 返 回 值: 成功则返回实际输出的字符数,失败返回-1. 函数说明: 使用过C语言的人所再熟悉不过 ...
- s5pc100开发板Nand flash移植
相关软件下载地址:http://pan.baidu.com/s/16yo8Y fsc100开发板 交叉编译工具:arm-cortex_a8-linux-gnueabi-gcc 添加针对我们平台 ...