题意:给定n个狼的战斗力,并且每个狼的战斗力还需要加上相邻的两个狼的额外的攻击力。当把这个狼杀死之后,它的额外的战斗力就不会给其它相邻的狼加了。每杀死一个狼,它就受到和狼攻击一样大的伤害。求杀死所有的狼最小受的伤害。
思路:区间dp,dp[i][j]表示从i到j最小的伤害,考虑[i, j]当中的第k个,假设k最后杀死,那么它受的伤害就是a[k] + b[i - 1] + b[j + 1],这里的a为狼的攻击力。b为额外攻击力。
不过在端点的时候要特殊判断。
/************************************************************************* > File Name: 4.cpp > Author: Howe_Young > Mail: 1013410795@qq.com > Created Time: 2015年09月22日 星期二 19时33分08秒 ************************************************************************/ #include <cstdio> #include <iostream> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> using namespace std; typedef long long ll; const int maxn = 221; const int inf = 0x3f3f3f3f; int a[maxn], b[maxn]; int dp[maxn][maxn]; int T, n; void init() { for (int i = 1; i <= n; i++) dp[i][i] = a[i] + b[i - 1] + b[i + 1]; for (int len = 1; len <= n; len++)//枚举区间的长度 { for (int i = 1; i + len <= n; i++)//枚举起点 { int j = i + len;//起点加上区间长度就是终点 dp[i][j] = inf;//初始化 for (int k = i; k <= j; k++)//[i, j]区间最后取k的时候 { if (k == i)//当[i,j]这个区间中i最后取的时候 { dp[i][j] = min(dp[i][j], dp[k + 1][j] + a[k] + b[i - 1] + b[j + 1]); } else if (k == j) { dp[i][j] = min(dp[i][j], dp[i][k - 1] + a[k] + b[i - 1] + b[j + 1]); } else dp[i][j] = min(dp[i][j], dp[i][k - 1] + dp[k + 1][j] + a[k] + b[i - 1] + b[j + 1]); } } } } int main() { int kase = 0; scanf("%d", &T); while (T--) { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); for (int i = 1; i <= n; i++) scanf("%d", &b[i]); b[0] = 0; b[n + 1] = 0; init(); printf("Case #%d: %d ", ++kase, dp[1][n]); } return 0; }