问题是求一个方案,实际隐含一个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. ASP.NET web application中的redirect

    在开发ASP.NET MVC web application过程中,开发上线了新系统后,需要把老系统的url redirect新系统下 其中在项目系统目录下有一个文件 301RedirectsPage ...

  2. Thinkphp5+plupload图片上传功能,支持实时预览图片。

    今天和大家分享一个国外的图片上传插件,这个插件支持分片上传大文件.其中著名的七牛云平台的jssdk就使用了puupload插件,可见这个插件还是相当牛叉的. 这个插件不仅仅支持图片上传,还支持大多数文 ...

  3. js基础(补10.10)

    1.内嵌式: <html> <head> <title></title> </head> <body> <a href=& ...

  4. java发送udp广播包

    2013-06-07 22:44 1272人阅读 评论(2) 收藏 举报 import java.io.IOException; import java.net.DatagramPacket; imp ...

  5. 数据库路由中间件MyCat - 使用篇(2)

    此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 基本概念 3. 分片 3.1 分片节点(dataNode) 表被水平切分后,每个分片表所在的数据库就是一个分 ...

  6. Unity5.5 Lighting Scene

    参考:https://docs.unity3d.com/Manual/GlobalIllumination.html Environment Lighting(环境光) Skybox: 天空盒材质,这 ...

  7. 51nod1102(单调栈/预处理)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1102 题意:中文题诶- 思路:单调栈/预处理 (这篇博客就不 ...

  8. solidity 学习笔记(6)call 函数

    call() 方法 call()是一个底层的接口,用来向一个合约发送消息,也就是说如果你想实现自己的消息传递,可以使用这个函数.函数支持传入任意类型的任意参数,并将参数打包成32字节,相互拼接后向合约 ...

  9. JavaScript进阶 - 第9章 DOM对象,控制HTML元素

    第9章 DOM对象,控制HTML元素 9-1 认识DOM 文档对象模型DOM(Document Object Model)定义访问和处理HTML文档的标准方法.DOM 将HTML文档呈现为带有元素.属 ...

  10. Netty(4-1)factorial~总结

    本节大纲: 1.Handler的执行顺序2.自定义二进制协议(每条完整数据的组成),从而解决拆包和粘包.3.通过为每个channel创建新的handler,从而解决即使handler中使用全局变量,也 ...