HDU 5115 (区间DP)
题目大意:你是一个战士现在面对,一群狼,每只狼都有一定的主动攻击力和附带攻击力。你杀死一只狼。你会受到这只狼的(主动攻击力+旁边两只狼的附带攻击力)这么多伤害~现在问你如何选择杀狼的顺序使的杀完所有狼时,自己受到的伤害最小。(提醒,狼杀死后就消失,身边原本相隔的两只狼会变成相邻,而且不需要考虑狼围城环这种情况)
输入要求:总共T组数据,每组N只狼,按顺序输入全部狼的主动攻击力和然后再按顺序输入全部狼的附带攻击力
输出要求:Case #x: y x第几组数据,y最少受到的伤害。
思路:枚举当前区间内最后一只杀死的狼是k,那么显然就是dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j]+a[k]+b[i-1]+b[j+1])。赛后看了题解也觉得不是很难想但训练过程中就是想不到这样的方法,看来还是得多写点区间DP的题,区间DP习惯写成dfs的形式,因为好写。
代码:
1 #include <iostream> 2 #include <queue> 3 #include <stack> 4 #include <cstdio> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <bitset> 9 #include <algorithm> 10 #include <cmath> 11 #include <cstring> 12 #include <cstdlib> 13 #include <string> 14 #include <sstream> 15 #include <time.h> 16 #define x first 17 #define y second 18 #define pb push_back 19 #define mp make_pair 20 #define lson l,m,rt*2 21 #define rson m+1,r,rt*2+1 22 #define mt(A,B) memset(A,B,sizeof(A)) 23 #define lowbit(x) (x&(-x)) 24 using namespace std; 25 typedef long long LL; 26 typedef unsigned long long ull; 27 //const double PI = acos(-1); 28 const int N=2e2+10; 29 //const int M=1e6+10; 30 const LL mod=10000007; 31 const int inf = 0x3f3f3f3f; 32 const LL INF=0x3f3f3f3f3f3f3f3fLL; 33 const double esp=1e-10; 34 LL dp[N][N]; 35 LL a[N],b[N]; 36 LL dfs(int l,int r) 37 { 38 LL res=INF; 39 if(l>r)return 0; 40 if(l==r)return dp[l][r]=a[l]+b[l-1]+b[r+1]; 41 if(dp[l][r]!=-1)return dp[l][r]; 42 for(int i=l;i<=r;i++) 43 { 44 res=min(res,dfs(l,i-1)+dfs(i+1,r)+a[i]+b[l-1]+b[r+1]); 45 } 46 return dp[l][r]=res; 47 } 48 int main() 49 { 50 #ifdef Local 51 freopen("data.h","r",stdin); 52 #endif 53 //ios::sync_with_stdio(false); 54 //cin.tie(0); 55 int T,cas=1,n; 56 cin>>T; 57 while(T--) 58 { 59 printf("Case #%d: ",cas++); 60 cin>>n; 61 for(int i=1;i<=n;i++)cin>>a[i]; 62 for(int i=1;i<=n;i++)cin>>b[i]; 63 mt(dp,-1); 64 b[0]=b[n+1]=0; 65 dfs(1,n); 66 cout<<dp[1][n]<<endl; 67 } 68 return 0; 69 #ifdef Local 70 cerr << "time: " << (LL) clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl; 71 #endif 72 }