题目大意:
一个长为L的棍子,有n个切分点,切割费用=被切割时木棍的长度,求最小的切割费用
分析:
区间$dp$。$dp[i][j]=[i,j]$区间的最小切割费用。状态转移方程$dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+a[j]-a[i]),a[i]$为每个切分点的位置。需要注意的是初始状态$dp[i][i+1]$就已经不能在被分割了所以要重置成$0$,$a[0]=0,a[n+1]=l$表示两个端点。
code:
#define debug
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e7;
const int MAXN = 5e3 + 10;
const ll INF = 0x3f3f3f3f;
const ll inf = 0x7fffff;
const ll mod = 1e9 + 7;
const int MOD = 10007;
int a[maxn];
int dp[MAXN][MAXN];
void solve() {
int l,n;
while(~scanf("%d",&l)&&l){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
a[n+1]=l;
memset(dp,INF,sizeof(dp));
for(int i=0;i<=n;i++)dp[i][i+1]=0;
for(int k=2;k<=n+1;k++){
for(int i=0;i+k<=n+1;i++){
for(int j=i;j<i+k;j++){
dp[i][i+k]=min(dp[i][i+k],dp[i][j]+dp[j][i+k]+a[i+k]-a[i]);
}
}
}
printf("The minimum cutting is %d.\n",dp[0][n+1]);
}
}
int main(int argc, char const *argv[]) {
// ios_base::sync_with_stdio(0);
// cin.tie(0);
// cout.tie(0);
#ifdef debug
freopen("in.txt", "r", stdin);
// freopen("out.txt","w",stdout);
#endif
int T=1;
// cin>>T;
while(T--)
solve();
return 0;
}