HDU 5115 Dire Wolf(区间dp)
题目大意
有n头狼排成一排,每只狼两个属性,攻击力和加成值,狼的实际攻击力等于自身攻击力加相邻狼的加成值,被杀死之后的狼对相邻的狼的攻击力的加成会被取消,同时,原先与 被杀死的狼相邻的两头狼会变成相邻的狼。问杀死所有狼受到的伤害值最小值。
解题思路
首先可以看出来第一行的数字对决策没什么影响,直接累加起来就是了。然后就是怎么决策的问题,一开始我以为是贪心找价值最大的点结果wa了。。。然后考虑区间dp。
这题区间dp的写法很简单,就是依次枚举区间的分割点然后进行合并就行了。
代码
const int maxn = 2e2+10;
const int maxm = 1e4+10;
ll a[maxn], b[maxn], dp[maxn][maxn];
int n, k;
int main() {
int t; cin >> t;
while(t--) {
scanf("%d", &n);
ll ans = 0;
for (int i = 1; i<=n; ++i) {
scanf("%lld", &a[i]); ans += a[i];
}
for (int i = 1; i<=n; ++i) scanf("%lld", &b[i]);
for (int i = 1; i<=n; ++i)
for (int j = 1; j<=n; ++j)
dp[i][j] = INF;
for (int i = 1; i<=n; ++i) dp[i][i] = b[i-1]+b[i+1];
for (int len = 1; len<=n; ++len) {
for (int l = 1; l+len<=n; ++l) {
int r = l+len;
dp[l][r] = min(dp[l+1][r]+b[l-1]+b[r+1], dp[l][r-1]+b[l-1]+b[r+1]);
for (int k = l+1; k+1<=r; ++k) dp[l][r] = min(dp[l][r], dp[l][k-1]+dp[k+1][r]+b[l-1]+b[r+1]);
}
}
printf("Case #%d: %lld\n", ++k, ans+dp[1][n]);
}
return 0;
}