例题9-9 UVa10003 Cutting Sticks(DP:矩阵链乘)

题意:

看白书

要点:

明显是类似于矩阵连乘问题,用d[i][j]标记i到j中的最优费用,从中间一点k处截成两半,可以写出状态转移方程为d[i][j] = min(d[i][j], d[i][k] + d[k][j] + pos[j] - pos[i]),不难看出这实际是一个区间DP问题,通过j-i小区间不断递增进行DP,注意这里i和j不用写成0~len,因为d[i][j]只是起到一个存储状态的作用,i和j应用来表示n个切割点的数组下标。


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
int len;
int pos[65],d[65][65];

int main()
{
	int i, j, k,l;
	while (scanf("%d", &len) && len)
	{
		int n;
		scanf("%d", &n);
		for (i = 1; i <= n; i++)
			scanf("%d", &pos[i]);
		pos[0] = 0; pos[n + 1] = len;//补上两个切割点
		for (i = 0; i <= n + 1; i++)
			d[i][i] = 0;
		for (l = 2; l <= n+1; l++)//这里实际i和j表示切割点对应下标即可
		{
			for (i = 0; i+l <=n+1; i++)
			{
				j = i + l;
				d[i][j] = 0xfffff;
				for (k = i+1; k < j; k++)
					d[i][j] = min(d[i][j], d[i][k] + d[k][j] + pos[j] - pos[i]);
			}
		}
		printf("The minimum cutting is ");
		printf("%d.\n", d[0][n+1]);
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值