问题是求一个方案,实际隐含一个dp。法力是递减的,所以状态是DAG,对于一个确定的状态,我们贪心地希望英雄的血量尽量大。

分析:定义状态dp[i][p][h]表示是已经用了i的法力值,怪兽的位置在p,怪兽的总血量为h时候英雄所具有的最大血量,

采用刷表法,决策有:

使用雷击,h变成h-L[p],p变成max(p-V,1),如果怪兽移动结束以后在1号位置且没有击杀怪物h-L[p]>0(注意这种情况),

会对英雄造成ceil((h-L[p])/HPm)点伤害,如果dp[i][p][h]-damge<=0,那么转移是非法的。

使用传送,传送到1是没有意义的,从2开始枚举,假设传送的位置为tp,那么怪物的下一个位置会是max(tp-V,1),处理一下伤害和转移即可。

使用治疗,注意判断一下血量上限。

具体处理的时候,记录一个pre状态数组和相应操作,用一个vis数组表示下一个阶段的状态是否出现过。

习惯用滚动数组,直接写反而觉得别扭。。。

转移麻烦的写个updata效果拔群

#include<bits/stdc++.h>
using namespace std;
const int maxn = ;
int N,HPh,MPh,HPm,Nm,V,dH;
int L[maxn]; #define MP make_pair
typedef pair<int,int> Node;
#define fi first
#define se second
#define PB push_back const int maxh = ;
int dp[][maxn][maxh];
bool vis[maxn][maxh];
char opt[][maxn][maxh];
Node pre[][maxn][maxh];
int optp[][maxn][maxh]; void print_ans(int i,Node rt)
{
printf("VICTORIOUS\n");
stack<Node> S; S.push(rt);
while(i>){
Node &u = S.top();
S.push(pre[i][u.first][u.second]); i--;
}
while(S.size()){
Node &u = S.top();
char ch = opt[i][u.fi][u.se];
putchar(ch);
if(ch == 'T') printf(" %d",optp[i][u.first][u.second]);
putchar('\n');
S.pop();
i++;
}
} void updata(int i,int nps,int Hm,char op,int opp,Node &u,int val,int (*nex)[maxh])
{
opt[i][nps][Hm] = op;//操作指令
optp[i][nps][Hm] = opp;//传送相关
pre[i][nps][Hm] = u;//前驱状态
nex[nps][Hm] = val;//更新val值
} void solve()
{
vector<Node> V1,V2,*q1 = &V1,*q2 = &V2;
q1->PB({N,Nm*HPm}); dp[][N][Nm*HPm] = HPh;
for(int i = ; i < MPh; i++){
memset(vis,,sizeof(vis));
int (*d1)[maxh] = dp[i&], (*d2)[maxh] = dp[(i&)^];//当前状态,和上一层状态
for(int j = ; j < (int)q1->size(); j++){
Node &u = q1->at(j);
//雷击
int nps = max(u.fi-V,);//怪兽移动后的位置 next_pos
int tHp = max(u.se-L[u.fi],);//攻击后怪兽的HP
int val = d1[u.fi][u.se];//英雄血量
int damege = ;
if(nps == ){ damege = (tHp+HPm-)/HPm;}//怪兽移动后到达1号格子,对英雄攻击
if(val-damege> || tHp == ){//英雄能承受攻击 或者 怪物已经死了
if(!vis[nps][tHp]){//状态判重
vis[nps][tHp] = true, q2->PB({nps,tHp});
updata(i,nps,tHp,'L',-,u,val-damege,d2);
if(tHp == ) {
print_ans(i,Node(nps,)); return;
} }else if(d2[nps][tHp] < val-damege){
updata(i,nps,tHp,'L',-,u,val-damege,d2);
if(tHp == ) {
print_ans(i,Node(nps,)); return;
}
}
}
//传送
for(int tp = ; tp <= N; tp++){//传送到tp位置
int tnps = max(tp-V,);//怪物移动 int tval = d1[u.first][u.second];
if(tnps == ){
tval -= (u.se+HPm-)/HPm;
}
if(tval>){
if(!vis[tnps][u.second]){
vis[tnps][u.se] = true,q2->PB({tnps,u.se});
updata(i,tnps,u.se,'T',tp,u,tval,d2);
}else if(d2[tnps][u.second] < tval){
updata(i,tnps,u.se,'T',tp,u,tval,d2);
}
} } if(nps == ){ damege = (u.se+HPm-)/HPm;}//未使用雷击时怪兽造成的伤害
else damege = ;
val = min(d1[u.fi][u.se]+dH,HPh);//治疗
if(val>damege){
val -= damege;
if(!vis[nps][u.se]){
vis[nps][u.se] = true; q2->PB({nps,u.se});
updata(i,nps,u.se,'H',-,u,val,d2);
}else if(d2[nps][u.se] < val){
updata(i,nps,u.se,'H',-,u,val,d2);
}
} }
q1->clear();
swap(q1,q2);
}
puts("DEFEATED");
} int main()
{
freopen("heroes.in","r",stdin);
freopen("heroes.out","w",stdout);
cin>>N>>HPh>>MPh>>HPm>>Nm>>V>>dH;
for(int i = ; i <= N; i++) scanf("%d",L+i);
solve();
return ;
}

2002-2003 ACM-ICPC Northeastern European Regional Contest (NEERC 02) H Heroes Of Might And Magic (隐含dp)的更多相关文章

  1. 2002-2003 ACM-ICPC Northeastern European Regional Contest (NEERC 02) A Amusing Numbers (数学)

    其实挺简单的.先直接算出之前已经排在k这个数前面的数字.比如543是三位的,那么100~543都是可以的,两位的10~54. 如果还需要往前面补的话,那么依次考虑1000~5430,5430是上界不能 ...

  2. 2002-2003 ACM-ICPC Northeastern European Regional Contest (NEERC 02)

    B Bricks 计算几何乱搞 题意: 给你个立方体,问你能不能放进一个管道里面. 题解: 这是一道非常迷的题,其问题在于,你可以不正着放下去,你需要斜着放.此时你需要枚举你旋转的角度,来判断是否可行 ...

  3. 2017-2018 ACM-ICPC Northern Eurasia (Northeastern European Regional) Contest (NEERC 17)

    2017-2018 ACM-ICPC Northern Eurasia (Northeastern European Regional) Contest (NEERC 17) A 题意:有 n 个时刻 ...

  4. Editing 2011-2012 ACM-ICPC Northeastern European Regional Contest (NEERC 11)

    NEERC 11 *wiki链接[[https://acm.ecnu.edu.cn/wiki/index.php?title=2011-2012_ACM-ICPC_Northeastern_Europ ...

  5. 2012-2013 ACM-ICPC Northeastern European Regional Contest (NEERC 12)

    Problems     # Name     A Addictive Bubbles1 addictive.in / addictive.out 2 s, 256 MB    x438 B Blin ...

  6. 2015-2016 ACM-ICPC Northeastern European Regional Contest (NEERC 15)C - Cactus Jubilee

    题意:给一颗仙人掌,要求移动一条边,不能放在原处,移动之后还是一颗仙人掌的方案数(仙人掌:无向图,每条边只在一个环中),等价于先删除一条边,然后加一条边 题解:对于一颗仙人掌,分成两种边,1:环边:环 ...

  7. 2017-2018 ACM-ICPC Northern Eurasia (Northeastern European Regional) Contest (NEERC 17) 日常训练

    A - Archery Tournament 题目大意:按时间顺序出现靶子和射击一个位置,靶子的圆心为(x, y)半径为r,即圆与x轴相切,靶子不会重叠,靶子被击中后消失, 每次射击找出哪个靶子被射中 ...

  8. 2015-2016 ACM-ICPC Northeastern European Regional Contest (NEERC 15)

    NEERC 15 题解1 题解2 官方题解

  9. ACM ICPC 2010–2011, Northeastern European Regional Contest St Petersburg – Barnaul – Tashkent – Tbilisi, November 24, 2010

    ACM ICPC 2010–2011, Northeastern European Regional Contest St Petersburg – Barnaul – Tashkent – Tbil ...

随机推荐

  1. 软件工程作业——Word Counter

    github地址 https://github.com/Pryriat/Word_Counter 项目说明 wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要求写一个命 ...

  2. WPF在ViewModel中绑定按钮点击(CommandBase定义)

    定义CommandBase public class CommandBase:ICommand { private readonly Action<object> _commandpara ...

  3. 黑马旅游网 url-pattern不加斜杠报错 java.util.concurrent.ExecutioException: org.apache.catalina.LifecycleException

  4. 14.插入数据、复制数据--SQL

    一.插入完整的行 要求指定表名和插入到新行中的值 INSERT INTO Customers ', 'Toy Land', '123 Any Street', 'New York', 'NY', ', ...

  5. ES6新特性使用小结(一)

    一.let const 命令 'use strict'; /*function test(){ //let a = 1; for(let i=1;i<3;i++){ console.log(i) ...

  6. [软件工程基础]2017.11.05 第九次 Scrum 会议

    具体事项 项目交接燃尽图 每人工作内容 成员 已完成的工作 计划完成的工作 工作中遇到的困难 游心 #10 搭建可用的开发测试环境:#9 阅读分析 PhyLab 后端代码与文档:#8 掌握 Larav ...

  7. [TCP/IP]TCP的三次握手和四次挥手

    概述 总结一下TCP中3次握手过程,以及其原生的缺陷 引起的SYN Flood的介绍 1.TCP连接建立--三次握手 几个概念: seq:序号,占4个字节,范围[0,4284967296],由于TCP ...

  8. 丝滑顺畅:使用CSS3获取60FPS动画

    原文链接: Smooth as Butter: Achieving 60 FPS Animations with CSS3 在移动端使用动画元素是很容易的. 如果你能遵循我们的这里的提示, 在移动端适 ...

  9. NET Core & Entity Framework Core

    ABP 教程文档 1-1 手把手引进门之 ASP.NET Core & Entity Framework Core(官方教程翻译版 版本3.2.5)   本文是ABP官方文档翻译版,翻译基于 ...

  10. Linux上常用命令整理(一)—— cat

    近几个月刚从windows上转过来,开始慢慢熟悉linux,先不撕比到底哪个更好,首先要怀着相互借鉴的精神去了解各个平台. Linux上做开发,除去使用文本编辑器做开发的大神之外,大家(包括我这种菜鸟 ...