例题9-9 UVA 10003 Cutting Sticks 切木棍(区间dp)

大体题意:

给你一个长度为L 的木棍,木棍上有n(n <= 50)个结点,切一刀的费用为当前木棍的长度值,问最后把这n个结点全部切掉的话,最小费用是多少!

思路:

用a[i] 记录第i 个结点的位置!

并把a[0] = 0,a[n+1] = L,这样做就可以处理边界情况了!

写个dp(i,j)函数记忆话搜索!

因为i j 之间必须有东西才可以处理嘛,所以直接判断i >= j-1的话,直接return 0;

因为是记忆话搜索  所以 如果d[i][j]如果不为-1的话  直接return d [i][j]
否则遍历i,j之间的东西!

转移方程为:

 dp(i,k) + dp(k,j) + a[j] - a[i];

更新d[i][j]即可!

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int l,n;
const int maxn = 50 + 5;
int d[maxn][maxn],a[maxn];
int dp(int i,int j){
	if (i >= j-1)return 0;
	if (d[i][j] >= 0)return d[i][j];
	for (int k = i + 1; k < j; ++k){
		int u = dp(i,k) + dp(k,j) + a[j] - a[i];
		if (u < d[i][j] || d[i][j] == -1)d[i][j] = u;
	}
	return d[i][j];
}
int main(){
	while(scanf("%d",&l) == 1 && l) {
		scanf("%d",&n);
		for (int i = 1; i <= n; ++i)scanf("%d",&a[i]);
		a[0] = 0;
		a[n+1] = l;
		memset(d,-1,sizeof d);
		printf("The minimum cutting is %d.\n",dp(0,n+1));
	}
	return 0;
}


你可能感兴趣的:(dp,C语言)