很清晰的区间dp问题。d(i,j)表示断点i到断点j的最小费用,由于开头和结尾也是断点,所以应该加入断点数组,即
cut[0]=0;
cut[n+1]=len;
边界就是d(i,i+1)=0;
转移方程:
for(int h=j+1;h<k;++h){
dp[j][k]=min(dp[j][k],dp[j][h]+dp[h][k]+cut[k]-cut[j]);
}
答案就是d(0,n+1)。
AC代码:
#include<cstdio>
#include<algorithm>
using namespace std;
const int inf=1<<25;
const int maxn=55;
int dp[maxn][maxn],cut[maxn];
int len,n;
int main(){
while(scanf("%d",&len)==1&&len){
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%d",&cut[i]);
}
cut[0]=0;
cut[n+1]=len;
for(int i=1;i<=n+1;++i){
for(int j=0;j<=n+1-i;++j){
int k=j+i;
dp[j][k]=inf;
if(i==1) dp[j][k]=0;
else for(int h=j+1;h<k;++h){
dp[j][k]=min(dp[j][k],dp[j][h]+dp[h][k]+cut[k]-cut[j]);
}
}
}
printf("The minimum cutting is %d.\n",dp[0][n+1]);
}
return 0;
}
如有不当之处欢迎指出!