蒜头君的坐骑
蒜头君的坐骑
题目大意
蒜头君有一只坐骑,人马。
一天,蒜头君骑着他的坐骑走上了一片 n \times mn×m 的大荒野,一开始时,蒜头君在 (1,1)(1,1) 点,他要前往 (n,m)(n,m) 点,蒜头君的人马每次可以向右或向下移动一格。然而这片荒野并不平静,除了起点和终点外每个点都有一只怪物会袭击蒜头君。
然而蒜头君的人马强大无比,它会先对怪物造成等同于它攻击力的伤害,然后蒜头君才会受到怪物的攻击,伤害等同于怪物的攻击力。然后人马再攻击怪物,怪物再攻击蒜头君,直至怪物死去,假设每个怪物具有相同的体力。
此外,蒜头君的人马还有一个强大无比的技能,使用该技能会使蒜头君接下来 kk 次移动,每一次移动后增加等同于移动到的格子的怪物的攻击力,kk 次移动后,人马攻击力恢复至初始攻击力。人马必须在当前一个技能释放完后才可以释放下一个技能,且一共可释放技能的次数有限,那么试问蒜头君从起点到终点最少受到多少点伤害。
注意:蒜头君的体力是无限的。
输入格式
第一行六个正整数 n,m,t,k,h,atkn,m,t,k,h,atk,表示地图长度、宽度、人马技能可使用次数、人马技能持续移动次数、每只怪物的体力和人马的初始攻击力。保证 n+m-1 \ge t \times kn+m−1≥t×k。
接下来 nn 行,每行 mm 个整数,表示每个点的怪物的攻击力。保证 (1,1)(1,1) 点、(n,m)(n,m) 点为 00,其他点为正整数。
输出格式
输出一个整数,表示蒜头君受到的最小伤害。
数据规模
对于 3030% 的测试数据,满足 1 \le n,m \le 10,1≤n,m≤10, 1 \le t \le 3,1≤t≤3, 1 \le k \le 31≤k≤3;
对于 6060% 的测试数据,满足 1 \le n,m \le 100,1≤n,m≤100, 1 \le t \le 10,1≤t≤10, 1 \le k \le 51≤k≤5;
对于 100100% 的测试数据,满足 1 \le n,m \le 500,1≤n,m≤500, 1 \le t \le 10,1≤t≤10, 1 \le k \le 5,1≤k≤5, 1 \le atk \le h \le 100,1≤atk≤h≤100, 1 \le1≤ 怪物攻击力 \le 100≤100。
样例输入
4 3 2 1 7 4 0 2 4 3 5 1 2 3 2 5 4 0
样例输出
3
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<algorithm> #include<cstring> using namespace std; int n,m,t,l,h,atk,map[501][501],ans=2e9,f[501][501][11]; int gi() { int ans=0,f=1; char i=getchar(); while(i<'0'||i>'9'){if(i=='-')f=-1;i=getchar();} while(i>='0'&&i<='9'){ans=ans*10+i-'0';i=getchar();} return ans*f; } int suan(int hurt,int attack) { return (h-1)/hurt*attack; } void dfs(int x,int y,int num,int k,int p,int attack) { if(num>l||(x==n&&y==m)) { f[x][y][k]=min(f[x][y][k],p); return; } if(x+1<=n)dfs(x+1,y,num+1,k,p+suan(attack+map[x+1][y],map[x+1][y]),attack+map[x+1][y]); if(y+1<=m)dfs(x,y+1,num+1,k,p+suan(attack+map[x][y+1],map[x][y+1]),attack+map[x][y+1]); } int main() { int i,j,k; n=gi();m=gi();t=gi();l=gi();h=gi();atk=gi(); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) map[i][j]=gi(); } memset(f,127/3,sizeof(f)); f[1][1][t]=0; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { for(k=t;k>=0;k--) { if(k)dfs(i,j,1,k-1,f[i][j][k],atk); if(i+1<=n)f[i+1][j][k]=min(f[i+1][j][k],f[i][j][k]+suan(atk,map[i+1][j])); if(j+1<=m)f[i][j+1][k]=min(f[i][j+1][k],f[i][j][k]+suan(atk,map[i][j+1])); } } } for(i=0;i<=t;i++) ans=min(ans,f[n][m][i]); printf("%d\n",ans); return 0; }