d(i,j)表示将第i个切割点到第j个切割点分成i-j段所花费的最小代价,d(i,j)=min(d(i,k)+d(k,j)+a(i)-a(j)),为什么可以这样设置,因为我们考虑(i,j)的最小切割代价的时候,只有第一刀的代价是可以直接知道的,以此可以作为状态间转移的“跳板”。
#include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> using namespace std; int l,n,cutt[55],d[55][55]; int main() { // freopen("1.txt","w",stdout); while(cin>>l&&l) { memset(d,0x3f3f3f,sizeof(d)); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&cutt[i]); cutt[n+1]=l; for(int i=0;i<=n-1;i++) d[i][i+2]=cutt[i+2]-cutt[i]; for(int i=0;i<=n;i++) d[i][i+1]=0; for(int i=3;i<=n+1;i++)//枚举切割数 for(int j=0;j<=n+1-i;j++) for(int k=j+1;k<=j+i-1;k++) d[j][j+i]=min(d[j][j+i],d[j][k]+d[k][j+i]+cutt[j+i]-cutt[j]); cout<<"The minimum cutting is "<<d[0][n+1]<<'.'<<endl; } }