题目:有一个长l的木头,切成n+1段,切割的代价是当前段长度,求最小代价和。
分析:dp,区间动态规划。石子合并的逆过程。
状态:设F(i,j)为从点i切到j长度的木头切割成对应的小段代价,则有转移方程:
F(i,j)= min(F(i,k)+F(k,j)+cost(i,j)) {其中 i < k < j };
这里注意,dp过程按区间大小递增顺序进行。
说明:注意边界条件,只有一小段时代价为0。
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
int cut[55];
int dp[55][55];
int main()
{
int l,n;
while (cin >> l >> n) {
for (int i = 1 ; i <= n ; ++ i)
cin >> cut[i];
cut[0] = 0; cut[n+1] = l;
//初始化,边界条件
for (int i = 0 ; i < 55 ; ++ i)
for (int j = 0 ; j < 55 ; ++ j)
dp[i][j] = 1000000;
for (int i = 0 ; i <= n ; ++ i)
dp[i][i+1] = 0;
//区间dp
for (int d = 2 ; d <= n+1 ; ++ d)
for (int s = 0 ; s+d <= n+1 ; ++ s)
for (int k = s+1 ; k < s+d ; ++ k)
if (dp[s][s+d] > dp[s][k]+dp[k][s+d]+cut[s+d]-cut[s])
dp[s][s+d] = dp[s][k]+dp[k][s+d]+cut[s+d]-cut[s];
cout << "The minimum cutting is "<< dp[0][n+1] << "." << endl;
}
return 0;
}