UVa 10003 - Cutting Sticks

来源:互联网 发布:文件阅读软件 编辑:程序博客网 时间:2024/06/05 15:29

转换思路后,类似矩阵链乘法、石子合并问题。

在长度为l的木棍上分布着n+1个点,依次从0-n+1编号,d[i][j]代表第i个点到第j个点中累加和的最小值。d[i][j] = min( d[i][j],d[i][k]+d[k][j] + (cut[j] - cut[i]) ),  (cut[i]为第i个点的“坐标“)

#include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> #include <stack> #include <queue> #include <iostream> #include <algorithm>  using namespace std;  #define MAXN 60 #define INF 1e9 #define MAX(a,b) (a>b?a:b) #define MIN(a,b) (a>b?b:a)  /*cut:每个点在长度为l木棍上的位置 */ int cut[MAXN],d[MAXN][MAXN]; int l,n;   int main() { #ifndef ONLINE_JUDGE freopen("data.in","r",stdin); //freopen("data.out","w",stdout); #endif  int i,j,k; while(scanf("%d",&l) && l > 0 ) { scanf("%d",&n); cut[0] = 0; cut[n+1] = l; for( i = 1; i <= n; i++ ) scanf("%d",&cut[i]);   memset(d,0,sizeof(d)); for( k = 1; k <= n+1; k++ )/*k为枚举的长度*/ for( i = 0; i <= n+1; i++ ) if(i+k <= n+1) {/*i为枚举的起点,i+k为枚举的终点*/ int ans = INF; for( j = i+1; j < i+k; j++ )/*枚举区间(i,i+k)中的点*/ if(d[i][j]+d[j][i+k]+cut[i+k]-cut[i] < ans ) ans = d[i][j]+d[j][i+k] + cut[i+k]-cut[i];  if(ans != INF) d[i][i+k] = ans; }  printf("The minimum cutting is %d.\n",d[0][n+1]);  }   return 0; }  

原创粉丝点击