HDU 5115 - 区间dp

Magic Door

题目大意:

有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;
} 
posted @ 2017-10-07 23:24  CzYoL  阅读(111)  评论(0编辑  收藏  举报