「JoyOI1459」穿越沙漠
描述 Description
魔法师小F来到了沙漠,他希望通过沙漠去挑战邪恶的魔法师。
这个是一个n*m的矩形沙漠,除了北面和南面,西边和东边都是特别高的大山,小F不会爬山。
沙漠中,每个地方都有一个邪恶魔法师召唤的邪恶的生物,每个生物都有自己的属性,“攻击力,防御力,血量”,当然,
小F同样也有“攻击力,防御力,血量”这3个属性,而且小F可以召唤其他生物来协助自己作战,被召唤的生物也有“攻击力,防御力,血量”
这3个属性。如果某个怪物的血量为0或者更少,那么就是一具尸体,小F可以轻松踏过尸体。
当小F或者小F的召唤兽和怪兽战斗的时候,每个回合都是小F或者小F的召唤兽先攻击,然后怪兽攻击,然后小F或者小F的召唤兽继续攻击,然后怪物再攻击,直到一方死去。 「战斗是不死不休的!」 当然,每和一个怪兽战斗,小F最多只能召唤一个召唤兽,不然会浪费太多的魔力。
但是召唤兽都很懒,所以他们最多只能被召唤一次(如果本回合用过这只召唤兽,那么下一回合召唤兽也不能被召唤)。 如果召唤兽被怪物杀死了,在战斗中,怪兽可能会掉血,那么小F可以亲自收拾残局,即接着怪物剩余血量和怪兽战斗。 只要怪兽不死,那么小F就不能走到被怪兽所占据的地方。小F希望保留最多的血通过沙漠(到达沙漠的南边),因为对面还有邪恶的魔法师等着他,因为沙漠缺水,小F节约时间不能在地图中东西走,也不能回头(即往北走),每次可以在当前位置向南(下),或者西南(左下方),东南方向(右下方),
战斗:
小F方单位攻击对方,对敌方单位造成 max(小F方攻击力-敌方防御力,0)的伤害。
敌方单位攻击小F方,对小F方单位造成 max(敌方攻击力-小F方防御力,0)的伤害。
小F方单位攻击对方,对敌方单位造成 max(小F方攻击力-敌方防御力,0)的伤害。
敌方单位攻击小F方,对小F方单位造成 max(敌方攻击力-小F方防御力,0)的伤害。
……
直到一方死亡(血量少于等于0为死亡)。
你可以认为如果小F和召唤兽同时攻击怪兽,只是召唤兽在和怪兽攻击,当召唤兽死了,那么小F在和怪兽战斗。
(总是小F的单位先攻击,如果攻击力低于对方防御力,那么无法对对方造成伤害,那么无法攻击对方,如果双方都无法攻击对方,那么小F只好不走这条路了)
输入格式 InputFormat
第一行2个数字: n,m,表示沙漠南北跨度,和东西跨度。
例如:当n=2 m=3时,地图为:
北
=====
西 |xxx|
|xxx| 东
—–
南
“x”表示怪兽
“|”表示大山,无法到达
“=”表示初始位置,为任意选择
“-“表示离开沙漠的位置,可以任意选择(只有沙漠中有怪物)
下面n行,每行m个数字,表示地图对应位置怪物的攻击力
下面n行,每行m个数字,表示地图对应位置怪物的防御力
下面n行,每行m个数字,表示地图对应位置怪物的初始血量
下面一行有3个数字,表示小F的攻击力,防御力,初始血量
下面一行一个数字p,表示小F拥有的召唤兽数量
下面p行,每行3个数字,分别为一个召唤兽的攻击力,防御力,血量
输出格式 OutputFormat
一行一个数字,表示小F最多剩余血量。如果小F无法活着走出沙漠,那么就输出-1
样例输入 SampleInput
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
样例1: 2 2 11 9 29 18 7 11 9 10 79 27 71 9 25 1 10000000 1 1 5 4 样例2: 5 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 2 100 0 |
样例输出 SampleOutput
1 2 3 4 5 |
样例1: 9999992 样例2: 100 |
数据范围和注释 Hint
数据范围:
0<=p<=10
0<=攻击力,防御力<=100
0<=怪物血量,召唤兽血量<=2000
0<=小F血量<=2^30
第一组数据满足 p=0,m=1
第二组数据满足 p=10,m=1
第三组数据满足 m=3
第四组数据满足 1<=n,m<=50,p=0
第五组数据满足 1<=n,m<=50,p=3
其余数据满足 1<=n,m<=50,p<=10
题解
出题人到底什么心态
数据到底什么心态
心态!
A完不写题解你们什么心态
这题是状压裸题你信吗,反正我是信了
主要把fight函数写清楚
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
#include<iostream> #include<cstring> #include<cstdio> #define inf 10000000 using namespace std; int h[11],ed,n,m,p,ans; int b1[51][51],b2[51][51],b3[51][51]; int a1,a2,a3,c1[11],c2[11],c3[11]; int f[51][51][1024]; void pre() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&b1[i][j]); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&b2[i][j]); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&b3[i][j]); scanf("%d%d%d",&a1,&a2,&a3); scanf("%d",&p); ed=(1<<p)-1; for(int i=1;i<=10;i++)h[i]=(1<<(i-1)); for(int i=1;i<=p;i++)scanf("%d%d%d",&c1[i],&c2[i],&c3[i]); for(int i=1;i<=m;i++)f[0][i][0]=a3; } int fight(int x,int y,int k) { int t1=c1[k],t2=c2[k],t3=c3[k]; int g1=b1[x][y],g2=b2[x][y],g3=b3[x][y]; if(t1>g2)//召唤兽能破防 { if(g1<=t2)return 0;//怪物不能破防 else { if(t3%(g1-t2)==0)g3-=(t3/(g1-t2))*(t1-g2);//注意这里 else g3-=(t3/(g1-t2)+1)*(t1-g2); } } if(g3<=0)return 0;//怪物挂了 if(a1<=g2)return inf;//人不能破防 if(g3%(a1-g2)==0)return max(0,(g3/(a1-g2)-1)*(g1-a2));//注意这里 return max(0,g3/(a1-g2)*(g1-a2)); } void work() { for(int x=1;x<=n;x++) for(int y=1;y<=m;y++) for(int i=0;i<=ed;i++) for(int j=0;j<=p;j++) if((h[j]|i)==i) { if(y>1)f[x][y][i]=max(f[x][y][i],f[x-1][y-1][i-h[j]]-fight(x,y,j)); f[x][y][i]=max(f[x][y][i],f[x-1][y][i-h[j]]-fight(x,y,j)); if(y<m)f[x][y][i]=max(f[x][y][i],f[x-1][y+1][i-h[j]]-fight(x,y,j));//转移 } } int main() { pre(); work(); for(int i=0;i<=ed;i++) for(int j=1;j<=m;j++) ans=max(ans,f[n][j][i]); if(ans<=0)printf("-1"); else printf("%d",ans); return 0; } |