题目大意:给定一根已知长度的木棍,给定n个切割点,要求按照切割点切割木棍,花费按照切割的木棍长度计算,例如有一根长10的木棍,切割点为2、4、7,如果按照2、4、7的顺序切割,花费将是10 + 8 + 6 = 24,如果按照4、2、7的顺序切割,那么花费将是10 + 4 + 6 = 20,切割顺序可以任意,要求花费最小
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
int len,n,i,j,k,p,a[55],dp[55][55];
while(scanf("%d",&len))
{
if(len==0)
break;
scanf("%",&n);
for(i=2;i<=n+1;i++)
scanf("%d",&a[i]);
a[1]=0;a[n+2]=len;
memset(dp,0,sizeof(dp));
for(p=1;p<=n+1;p++)
{
for(i=1;i<=n+1;i++)
{
j=p+i;
for(k=i;k<j;k++)//dp[i][j]切割区间[i,j]的最小代价
dp[i][j]=min(dp[i][k]+dp[k+1]j]+a[j]-a[i]);
}
}
printf("The minimum cutting is%d.\n",dp[1][n+2]);
}
}
/*设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个点*/