问题是求一个方案,实际隐含一个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. java.endorsed.dirs的作用

    java.endorsed.dirs   java.ext.dirs 用于扩展jdk的系统库,那么 -Djava.endorsed.dirs 又有什么神奇的作用呢? java提供了endorsed技术 ...

  2. Windows对象、句柄与MFC对象

    windowsmfc编程c 目录(?)[-] Windows对象句柄与MFC对象 windows对象 句柄 mfc对象 杂谈 Windows对象.句柄与MFC对象 (2009-04-28 22:11: ...

  3. pandas基础(2)_多重索引

    1:多重索引的构造 >>> #下面显示构造pd.MultiIndex >>> df1=DataFrame(np.random.randint(0,150,size= ...

  4. chrome调式工具

    1.Elementshttps://segmentfault.com/a/1190000008316690 2. Consolehttps://segmentfault.com/a/119000000 ...

  5. 动态生成navmeshi-进击的新版NavMesh系统:看我飞檐走壁

    http://forum.china.unity3d.com/thread-25421-1-1.html0x00 前言 unity5.6作为Unity5最后的一个版本,的确起到了一个承上启下的作用.除 ...

  6. AES 加密 PHP 和 JAVA 互通

    PHP代码: <?php class Security { public static function encrypt($input, $key) { $size = mcrypt_get_b ...

  7. 洛谷P3172 [CQOI2015]选数(容斥)

    传送门 首先,进行如下处理 如果$L$是$K$的倍数,那么让它变成$\frac{L}{K}$,否则变成$\frac{L}{K}+1$ 把$H$变成$\frac{H}{K}$ 那么,现在的问题就变成了在 ...

  8. python——基本数据类型1——简介

    列表 列表是可变数据类型.是序列类型; 列表的内容可以是数字,字符串和其它列表: 0第一个元素,-1最后一个元素, 定义连续列表 li = list(range(1,10,2)) 列表取值: 取 b: ...

  9. Jmeter 的 vars 和 props 用法

    meter 的 JSR223 控件是 代替 BeanShell 的新一代脚本控件,支持多种脚本语言,尤其是其中的 Groovy,更是重点推荐使用的脚本语言,本文研究其中的 vars 和 props 两 ...

  10. Django-Rest-Framework的版本和认证

    Django-Rest-Framework的版本和认证   restful framework DRF的版本 版本控制是做什么用的,我们为什么要用 首先要知道版本是干嘛用的,我们知道开发项目的时候有多 ...