题目链接:
题目描述:
面对一群恶狼进行战斗,每个狼都有自己的攻击力,但是每个狼也能给其相邻的狼提供一定量的Buff加成。消灭一只狼花费的代价是自身攻击力加上其他狼给他的加成,问消灭所有的狼花费最小的代价是多少?
解题思路:
区间dp,刚开始想了好多个贪心策略都搞不定。最后仔细看了下,发现符合区间DP的性质,狼i被消灭以后,i-1与i+1变成了相邻的。所以可以用区间Dp来进行状态转移。
dp[x][y] 表示 消灭区间[x, y]的狼最小花费的代价,
dp[i][i] = a[i] + b[i-1] + b[i+1];
dp[i][j] = max (dp[i][j], dp[i][k-1] + dp[k+1][j] + a[k] + b[i-1] + b[j+1]), 其中i<=k<=j;
再注意一下边界处理就好啦!
1 #include <queue> 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 7 using namespace std; 8 const int maxn = 210; 9 10 int dp[maxn][maxn], a[maxn], b[maxn]; 11 12 int main () 13 { 14 int T; 15 scanf ("%d", &T); 16 17 for (int t=1; t<=T; t++) 18 { 19 int n; 20 scanf ("%d", &n); 21 22 for (int i=1; i<=n; i++) 23 scanf ("%d", &a[i]); 24 for (int i=1; i<=n; i++) 25 scanf ("%d", &b[i]); 26 27 a[0] = b[0] = a[n+1] = b[n+1] = 0; 28 for (int i=1; i<=n; i++) 29 dp[i][i] = a[i] + b[i-1] + b[i+1]; 30 31 for (int i=1; i<=n; i++) 32 for (int l=1; l+i<=n; l++) 33 { 34 int r = i + l; 35 int res = b[r+1] + b[l-1]; 36 37 dp[l][r] = min (dp[l+1][r]+a[l]+res, dp[l][r-1]+a[r]+res); 38 39 for (int k=l+1; k<r; k++) 40 dp[l][r] = min (dp[l][k-1]+dp[k+1][r]+a[k]+res, dp[l][r]); 41 42 } 43 printf ("Case #%d: %d ", t, dp[1][n]); 44 } 45 return 0; 46 }