您的位置:首页 > 其它

西安集训第二天---状压dp

2017-08-07 17:36 190 查看
热身题:

https://nanti.jisuanke.com/t/16447

挺有意思的一道题,标准的dp

我的思路+代码:

dp[i][j][k][r] 走到i,j 这个点,已经用过几个技能了,并且当前能力值还剩下几步。的最小伤害

r=0 表示当前没有buff。

dp[505][505][15][10]; // 500*500*10*5 =12500000

下面我们考虑一下 转移方程:

对于i,j

dp[i][j][k][r] = ( dp[i-1][j][k][r+1] dp[i][j-1][k][r+1] ) 但是我们无法知道攻击力是多少,所以无法转移,

但是如果我们吧增加的攻击力放入其中,那么需要100*250000显然太大了

正解:

因为我们只需要终点的状态

且为了最优解肯定是技能结束的状态,所以我们不需要讨论开技能时候的转移,我们只需要开完技能之后的状态转移即可。

我们考虑 dp[i][j][k] 表示到ij这个点 用了k次技能,如果这个点 不使用技能那么转移

如果使用技能我们直接dfs 更新这一次决策可能结束的位置,以及对应位置的伤害,然后更新相对应位置的dp值。 因为每次只能走五步,所以这个dfs的复杂度并不高

总的时间复杂度= 500*500*10*6??? 好像最多只会更新6个位置

有一个细节:

假设在某个点开始一个技能

那么dfs中的伤害s 代表的是已经走到i,j的伤害值,所以这个点的伤害必然是不需要计算了的

同时这个点的攻击力也是不能加的

#include <bits/stdc++.h>
using namespace std;
int dp[505][505][15];
int a[505][505];
int n,m,t,kk,atk,h;
int count(int x,int y){  // 计算伤害  敌方攻击,我方攻击
int num=(h-1)/y;
return x*num;
}
void dfs(int K,int i,int j,int ATK,int rest,int s){ // 这是第几次发动技能,i,j点,当前的攻击力,还能走几步,累计的伤害值
if(rest<kk){
s+=count(a[i][j],ATK+a[i][j] ); // 第一个点的伤害是不能计算的
ATK+=a[i][j];
}
if(rest==0){  //  这一步是最后一步
dp[i][j][K]=min(dp[i][j][K],  s);
// printf("end:%d %d %d  atk=%d  shanghai =%d %d\n",i,j, K,ATK+a[i][j], count(a[i][j],ATK+a[i][j]) ,dp[i][j][K]);
return;
}
if(i<n) // ->
dfs(K,i+1,j,ATK,rest-1,s );
if(j<m)
dfs(K,i,j+1,ATK,rest-1,s );
}
int main(){
freopen("1.txt","r",stdin);
scanf("%d %d %d %d %d %d",&n,&m,&t,&kk,&h,&atk);
for(int k=0;k<=t;k++)
for(int i=0;i<=n;i++)
for(int j=0;j<=m;j++)
dp[i][j][k]=1<<30;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);

for(int i=0;i<=t;i++)
dp[1][1][i]=0;
for(int k=0;k<=t;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
// 首先考虑在这个点不用技能,向右或者下走
if(i+1<=n)
dp[i+1][j][k] = min( dp[i+1][j][k], dp[i][j][k]+count(a[i+1][j],atk) );
if(j+1<=m)
dp[i][j+1][k] = min(dp[i][j+1][k] , dp[i][j][k]+count(a[i][j+1],atk));
if(k<t){ // 能够用技能 ,已经用了k次
// printf("dfs: %d %d  k=%d s=%d \n\n",i,j,k+1,dp[i][j][k]);
dfs(k+1,i,j,atk,kk,dp[i][j][k]);
}
}
printf("%d\n",dp
[m][t]);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: