csu1646 HearthStone

来源:互联网 发布:sql tools 编辑:程序博客网 时间:2024/05/24 03:40

这里写图片描述
好久没有写dp,这题算很基础.
dp首先定义状态:dp[i][j][k]:当进行到第i轮,达拉然法师出场j个,刺骨使用k次情况下的最大伤害。
仔细考虑,还有每轮的费用,法师,刺骨使用几张的情况这些并不需要定义成状态。开始我想复杂,把这些也定义成状态,结果状态转移方程反而不好写。这里就要思考一个变换过程中并不是要把每一个变换都设置为状态的一个变量,只要拍你定义的状态容易写出状态转移方程,并能正确求解这个过程就是好的dp解法。
定义好了状态:就是考虑每轮在费用一定的情况下,你可以选择 只有添加法师和刺骨数量的不同。这样状态转移方程就可以慢慢推。注意一个条件在某一轮内,若在使用刺骨之前使用过至少一张卡,则可额外造成2点伤害,分情况转移一下!

#include<bits/stdc++.h>using namespace std;int dp[25][210][210];//定义dp[i][j][k] 定义当前i轮过后使用了j张法师,k个刺骨的最大伤害int main(){    int T;scanf("%d",&T);    while(T--){        int r,n,m;scanf("%d%d%d",&r,&n,&m);        memset(dp,-1,sizeof(dp));        dp[1][0][0]=0;        for(int i=1;i<r;i++){          for(int j=0;j<=n;j++){            for(int k=0;k<=m;k++){               if(dp[i][j][k]==-1) continue;               int f=(i+1)<10 ? (i+1): 10;               for(int d=0;d<=f/3;d++){                  if(j+d<=n){                    for(int c=0;c<=f/2;c++){                      if(k+c<=m&&d*3+c*2<=f){                         if(d==0&&c!=0) dp[i+1][j][k+c]=max(dp[i+1][j][k+c],dp[i][j][k]+j+(j+d+4)*c-2);                         else  dp[i+1][j+d][k+c]=max(dp[i+1][j+d][k+c],dp[i][j][k]+j+(j+d+4)*c);                      }                    }                  }               }            }          }        }        int maxn=0;        for(int i=0;i<=n;i++){            for(int j=0;j<=m;j++){                maxn=max(maxn,dp[r][i][j]);            }        }        printf("%d\n",maxn);    }}
1 0