https://vjudge.net/problem/UVA-10003
给一个0-L长度的木板,然后给N个数,表示0-L之间的某个刻度,最后要用刀把每个刻度都切一下 使其断开,然后每次分裂的cost是分裂前的木板的长度。求整个分开之后的最小cost。
思路:d(i,j)表示切割小木棍(i,j)的最优费用,d(i,j)=min(d(i,k)+d(k,j)|i<k<j)+tp[j]-tp[i] ,后面的附加的是切割费用。枚举区间起点i和终点j,和分割区间的那个点k,找出最小的。然后不断的递推。
注意,这里的ij不是木板的长度刻度,是切割点的编号,ij的范围是(0,n),不是(0,l)
这里使用dp+memerizion方法。
#include<iostream>
#include<vector>
#include<cmath>
#include<algorithm>
#include<string.h>
using namespace std;
#define INT_MAX 1000000
#define MAX 1005
int vist[MAX][MAX];
vector<int> tp(MAX,0);
int main() {
int cut(int i,int j);
int l,n,temp;
while(scanf("%d",&l)==1&&l) {
scanf("%d",&n);
memset(vist,-1,sizeof(vist));
tp.resize(n+2);
tp[0]=0;
tp[n+1]=l;
for(int i=0; i<n; i++) {
scanf("%d",&tp[i+1]);
}
temp=cut(0,n+1);
cout<<"The minimum cutting is "<<temp<<"."<<endl;
}
}
int cut(int i,int j) {
if(vist[i][j]>=0) return vist[i][j];
if(i+1==j) return vist[i][j]=0;
else {
int imin=INT_MAX;
for(int k=i+1; k<j; k++) {
imin=min(cut(i,k)+cut(k,j)+tp[j]-tp[i],imin);
}
return vist[i][j]=imin;
}
}