当前位置: 代码迷 >> 综合 >> Cutting Sticks
  详细解决方案

Cutting Sticks

热度:83   发布时间:2024-01-25 22:55:20.0

在这里插入图片描述
UVA10003
这是一道区间动态规划
定义 d p [ i ] [ j ] dp[i][j] 为第 i i 个切割点到第 j j 个切割点之间的木条的最小切割费用, P o i n t [ i ] Point[i] 为第 i i 个切割点的位置。
初始化
d p [ i ] [ i + 1 ] = 0 dp[i][i+1]=0
因为相邻切割点之间没有切割点,不需要切割。
P o i n t [ 0 ] = 0 P o i n t [ n + 1 ] = L ( ) Point[0]=0\\Point[n+1]=L(木条长度)
在头和尾也添加切割点,方便枚举
转移方程
d p [ i ] [ j ] = m i n ( d p [ i ] [ k ] + d p [ k ] [ j ] ) + P o i n t [ j ] ? P o i n t [ i ] ( i < k < j ) dp[i][j]=min(dp[i][k]+dp[k][j])+Point[j]-Point[i](i<k<j)
i i j j 要切成 i k ik k j kj ,需要花费 i j ij 长度的代价,即 P o i n t [ j ] ? P o i n t [ 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;
}