1489 蜥蜴和地下室 51NOD
2017-04-08 10:53
323 查看
哈利喜欢玩角色扮演的电脑游戏《蜥蜴和地下室》。此时,他正在扮演一个魔术师。在最后一关,他必须和一排的弓箭手战斗。他唯一能消灭他们的办法是一个火球咒语。如果哈利用他的火球咒语攻击第i个弓箭手(他们从左到右标记),这个弓箭手会失去a点生命值。同时,这个咒语使与第i个弓箭手左右相邻的弓箭手(如果存在)分别失去b(1 ≤ b < a ≤ 10)点生命值。
因为两个端点的弓箭手(即标记为1和n的弓箭手)与你相隔较远,所以火球不能直接攻击他们。但是哈利能用他的火球攻击其他任何弓箭手。
每个弓箭手的生命值都已知。当一个弓箭手的生命值小于0时,这个弓箭手会死亡。请求出哈利杀死所有的敌人所需使用的最少的火球数。
如果弓箭手已经死亡,哈利仍旧可以将他的火球扔向这个弓箭手。
Input
第一行包含3个整数 n, a, b (3 ≤ n ≤ 10; 1 ≤ b < a ≤ 10),第二行包含n个整数——h1,h2,…,hn (1 ≤ hi ≤ 15), hi 是第i个弓箭手所拥有的生命力。
Output
以一行输出t——所需要的最少的火球数。
Input示例
3 2 1
2 2 2
Output示例
3
想了好久的一个DP题(好弱,,,),两端敌人是无法直接攻击到的,杀死他们的办法是唯一的,所以首先贪心处理两端的敌人,然后题目要求有点奇葩,每个人还得生命值小于0才死,所以在开始直接给每个人的生命值+1,然后当成生命值为0的时候死去做。
之后对处理完的敌人可以这样考虑,首先定义状态:
dp[i][j][k][l]表示对于第i个人,自己状态为k,前一个人状态为j,后一个人状态为l时所需发射最小火球术。
如果你对第i个人进行直接火球攻击,那么对i,j,k分别减去对应的值,得到子状态进行更新,然后如果j==0时,还应更新:
dp[i+1][k][l][num[i+2]]的值。
因为两个端点的弓箭手(即标记为1和n的弓箭手)与你相隔较远,所以火球不能直接攻击他们。但是哈利能用他的火球攻击其他任何弓箭手。
每个弓箭手的生命值都已知。当一个弓箭手的生命值小于0时,这个弓箭手会死亡。请求出哈利杀死所有的敌人所需使用的最少的火球数。
如果弓箭手已经死亡,哈利仍旧可以将他的火球扔向这个弓箭手。
Input
第一行包含3个整数 n, a, b (3 ≤ n ≤ 10; 1 ≤ b < a ≤ 10),第二行包含n个整数——h1,h2,…,hn (1 ≤ hi ≤ 15), hi 是第i个弓箭手所拥有的生命力。
Output
以一行输出t——所需要的最少的火球数。
Input示例
3 2 1
2 2 2
Output示例
3
想了好久的一个DP题(好弱,,,),两端敌人是无法直接攻击到的,杀死他们的办法是唯一的,所以首先贪心处理两端的敌人,然后题目要求有点奇葩,每个人还得生命值小于0才死,所以在开始直接给每个人的生命值+1,然后当成生命值为0的时候死去做。
之后对处理完的敌人可以这样考虑,首先定义状态:
dp[i][j][k][l]表示对于第i个人,自己状态为k,前一个人状态为j,后一个人状态为l时所需发射最小火球术。
如果你对第i个人进行直接火球攻击,那么对i,j,k分别减去对应的值,得到子状态进行更新,然后如果j==0时,还应更新:
dp[i+1][k][l][num[i+2]]的值。
#include<bits/stdc++.h> using namespace std; #define D(x,t) x-a*t>0?x-t*a:0 #define ID(x,t) x-b*t>0?x-t*b:0 const int INF=0X7fffffff; int dp[20][20][20][20]; //dp[i][i-1][i][i+1]:当对第i个敌人直接发射火球时可能的状态,i为第k-1的人,j为第k个人 int n,a,b; int main() { while(cin>>n>>a>>b) { int num[25]; int sum_times=0; memset(num,0,sizeof(num)); for(int i=0;i<n;i++) { scanf("%d",&num[i]); num[i]++; } //先对数据进行处理 int times=ceil((double)num[0]/b); sum_times+=times; num[1]=D(num[1],times); num[2]=ID(num[2],times); times=ceil((double)num[n-1]/b); sum_times+=times; num[n-2]=D(num[n-2],times); num[n-3]=ID(num[n-3],times); num[0]=num[n-1]=0; //初始化为无穷大 for(int i=0;i<20;i++) for(int j=0;j<20;j++) for(int k=0;k<20;k++) for(int l=0;l<20;l++) dp[i][j][k][l]=INF; dp[1][0][num[1]][num[2]]=0; for(int i=1;i<n-1;i++) for(int l=num[i+1];l>=0;l--) for(int k=num[i];k>=0;k--) for(int j=num[i-1];j>=0;j--) { if(dp[i][j][k][l]!=INF) { int z=0; while(1) { // cout<<2<<endl; int aa=ID(j,z); int bb=D(k,z); int cc=ID(l,z); dp[i][aa][bb][cc]=min(dp[i][j][k][l]+z,dp[i][aa][bb][cc]); if(!aa) dp[i+1][bb][cc][num[i+2]]=min(dp[i][j][k][l]+z,dp[i+1][bb][cc][num[i+2]]); z++; if(!bb&&!aa&&!cc) break; } } } cout<<dp[n-1][0][0][0]+sum_times<<endl; } }
相关文章推荐
- 51nod 1489 蜥蜴和地下室
- 51nod 1489 蜥蜴和地下室 暴力dfs
- 51nod 1489蜥蜴和地下室
- 蜥蜴和地下室 51Nod - 1489
- 51Nod 1489 蜥蜴和地下室
- 51nod 1489 蜥蜴和地下室 dfs
- 51Nod-1489-蜥蜴和地下室
- 51Nod-1489 蜥蜴和地下室(暴力DFS)
- 51Nod-1489-蜥蜴和地下室
- 51Nod 1489 蜥蜴和地下室 DFS
- 51nod 1489 蜥蜴和地下室(dfs or dp)
- 51nod 1489 蜥蜴和地下室(dfs)
- JAVA学习45_51Nod-1489-蜥蜴和地下室
- 51nod 1489 蜥蜴和地下室 dfs
- 51Nod 1489 蜥蜴和地下室
- 51nod 1489 蜥蜴和地下室
- 51nod 1489 蜥蜴和地下室(DFS)
- 【51Nod】1489 - 蜥蜴和地下室(dfs)
- 51 Nod 1489 蜥蜴与地下室(DFS)
- 51nod--蜥蜴和地下室