uva 10003 Cutting Sticks 切木条dp

这道题有些类似矩阵连乘,就是区间的问题。设dp[i][j]表示从i到j的最小花费,那么dp[i][j]=min{dp[i]

[k]+dp[k][j]+a[j]-[i]}(i<k<j)其中a[j]-a[i]表示从i到j的长度,即要切这块木条所需的花费。求大区

间得时候小区间已经算出来了,所以符合动态规划的自底向上,而且是最优子结构,这道题我把0和木条长度加到了a

数组里面,就是说一共有n+2个点,每两个相邻的点不用切割,初始化为1

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<vector>
#include<set>
#include<string>
#include<algorithm>

using namespace std;

int main()
{
	int s,n;
	int dp[55][55];
	int a[55];
	int i,j,r,k,t,m;
	while(cin >> s,s)
	{
		cin >> n;
		a[1] = 0;
		a[n+2] = s;
		for(i=2; i<=n+1; i++)
			cin >> a[i];
		m = n+2;
		for(i=1; i<m; i++)
			dp[i][i+1] = 0;
		for(r=2; r<=m-1; r++)//r表示区间的长度,最短为2,最长为m-1 
		{
			for(i=1; i<=m-r; i++)//i表示区间的起点,最小为1,最长得根据r求出 
			{
				j=i+r;//j表示区间的中点 
				dp[i][j] = dp[i+1][j] +dp[i][i+1] + a[j]-a[i];
				for(k=i+2; k<j; k++)
				{
					t = dp[i][k] + dp[k][j] + a[j] - a[i];
					if(t < dp[i][j])
						dp[i][j] = t;
				}
			}
		}
		cout << "The minimum cutting is "<< dp[1][m] << '.'<< endl;
	}
	return 0;
}


你可能感兴趣的:(uva 10003 Cutting Sticks 切木条dp)