例题9-9 UVA 10003 Cutting Sticks 切木棍(最优三角剖分 || 区间dp )

大体题意:

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



不看下面的思路,自己又重新思考了一遍    2016.10.9   21:19

这就是最优三角剖分或者叫 最优矩阵链乘!

直接记忆化搜索即可! 枚举切得中间哪一刀即可!然后分成两部分去dfs!在加上权值(棍子长度即可!)

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


====================================



思路:

用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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值