在这里插入图片描述
UVA10003
这是一道区间动态规划
定义dp[i][j]dp[i][j]为第ii个切割点到第jj个切割点之间的木条的最小切割费用,Point[i]Point[i]为第ii个切割点的位置。
初始化
dp[i][i+1]=0dp[i][i+1]=0
因为相邻切割点之间没有切割点,不需要切割。
Point[0]=0Point[n+1]=L()Point[0]=0\\Point[n+1]=L(木条长度)
在头和尾也添加切割点,方便枚举
转移方程
dp[i][j]=min(dp[i][k]+dp[k][j])+Point[j]Point[i](i<k<j)dp[i][j]=min(dp[i][k]+dp[k][j])+Point[j]-Point[i](i<k<j)
iijj要切成ikikkjkj,需要花费ijij长度的代价,即Point[j]Point[i]Point[j]-Point[i]
AC代码

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int dp[51][1001], L, n, Point[52];
bool Input() {
	cin >> L;
	if (!L) {
		return false;
	}
	cin >> n;
	for (int i = 1; i <= n; ++i) {
		cin >> Point[i];
	}
	return true;
}
int DP() {

	Point[n + 1] = L;
	dp[0][1] = 0;

	for (int i = 1; i <= n; ++i) {
		dp[i][i + 1] = 0;
	}
	//枚举区间长度
	for (int NumberOfPoint = 2; NumberOfPoint <= n + 1; NumberOfPoint++) {
		//枚举起点
		for (int i = 0; i + NumberOfPoint <= n + 1; i++) {
			int
				&&j = i + NumberOfPoint,
				&&minn = 0xfffffff;
			//枚举中转点
			for (int k = i + 1; k < j; k++) {
				minn = min(minn, dp[i][k] + dp[k][j]);
			}
			dp[i][j] = minn + Point[j] - Point[i];
		}
	}

	return dp[0][n + 1];
}
int main() {
	ios::sync_with_stdio(false);
	while (Input()) {
		cout << "The minimum cutting is " << DP() << "." << endl;
	}
	return 0;
}
posted on 2020-01-18 19:02  SCU_GoodGuy  阅读(137)  评论(0)    收藏  举报