10003 - Cutting Sticks
描述:题目难度为 2,将一条长为n的木棍切成m+1块,但是切割顺序不同,寻找状态方程s[x][y]=min(s[x][y],s[x][i]+s[i][y]+s[y]-s[x]);然后就可以敲代码了 代码一(递归,耗时较多): #include <cstdio> #include <cstring> int num[55],s[55][55]; int min(int a,int b) { if(a>b) return b; else return a; } int dp(int x,int y) { if(y-x==1) return 0; if(s[x][y]>0) return s[x][y]; s[x][y]=1000000; for(int k=x+1; k<y; k++) s[x][y]=min(s[x][y],dp(x,k)+dp(k,y)+num[y]-num[x]); return s[x][y]; } int main() { // freopen("a.txt","r",stdin); int n,m; while(scanf("%d",&n)!=EOF) { if(!n) break; memset(s,0,sizeof(s)); scanf("%d",&m); num[m+1]=n; for(int i=1; i<=m; i++) scanf("%d",&num[i]); printf("The minimum cutting is %d.\n",dp(0,m+1)); } return 0; } 代码二(耗时少): #include <cstdio> #include <cstring> int num[55],s[55][55]; int min(int a,int b) { if(a>b) return b; else return a; } int main() { // freopen("a.txt","r",stdin); int n,m; while(scanf("%d",&n)!=EOF) { if(!n) break; memset(s,0,sizeof(s)); scanf("%d",&m); num[m+1]=n; for(int i=1; i<=m; i++) scanf("%d",&num[i]); int k=2,x=0; for( ; x+k<=m+1&&k<=m+1; x++) { int y=x+k; if(!s[x][y]) s[x][y]=1000000; for(int i=x+1; i<=y; i++) s[x][y]=min(s[x][y],s[x][i]+s[i][y]+num[y]-num[x]); if(y==m+1&&!x) break; if(x+k==m+1) { x=-1; k++; } } printf("The minimum cutting is %d.\n",s[0][m+1]); } return 0; }