HDU 5115 - 区间dp
题目大意:
有n匹狼, 每个狼有属性值a和b, 要想杀死一匹狼需要付出该狼的a以及左右相邻的b(若没有则不加),问杀死所有狼的最小代价。
题目分析
区间dp: dp[i][j]表示杀死i~j的最小代价, 枚举最后杀死的一匹狼则有
\[dp[i][j] = min\{dp[i][k - 1] + dp[k + 1][j] + a[k] + b[i - 1] + b[j + 1]\}(i <= k <= j)
\]
注意边界值即为:
\[dp[i][i] = a[i] + b[i - 1] + b[i + 1]
\]
code
#include<bits/stdc++.h>
using namespace std;
const int N = 205, OO = 0x3f3f3f3f;
int n, a[N], b[N], dp[N][N];
inline int DP(int l, int r){
if(l > r) return 0;
if(dp[l][r] != -1) return dp[l][r];
if(l == r) return dp[l][r] = a[l] + b[l - 1] + b[r + 1];
int tmp = OO;
for(int k = l; k <= r; k++)
tmp = min(tmp, DP(l, k - 1) + DP(k + 1, r) + a[k] + b[l - 1] + b[r + 1]);
return dp[l][r] = tmp;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL), cout.tie(NULL);
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n; i++) cin >> b[i];
memset(dp, -1, sizeof dp);
cout << DP(1, n);
return 0;
}