题目里讲的是归并。 用递归做
[ 本帖最后由 sunyh1999 于 2010-9-24 07:55 编辑 ]
[ 本帖最后由 sunyh1999 于 2010-9-24 07:55 编辑 ]
欢迎来到我的博客:http://blog..cn/noisunyuhong
#include <stdio.h> #define MAXL 400 //定义最大测资为400 int book[MAXL]; int f[MAXL][MAXL]; //f[i][j] (i<=j) 存放i~j合并为一堆的最小力气花费,若i>j,则为-1 long int strength=0; //strength为总合并重量 void print()//打印结果 { printf("%ld\n",strength); } int sum(int start,int end) //计算从起点到终点的累加和 { int i,s=0; for(i=start;i<=end;i++) { s+= book[i]; } return s; } int min_strength(int s, int e) //求从s开始到e结束合并为一堆的最小力气花费 { int i,j,k,min=99999999; //min 存放最小值,初始其为一个很大的数,可以改为int类型的最大数 if(s==e) //起点和终点为一个点 return 0; if(s==e-1) //起点和终点相邻 { f[s][e]=sum(s,e); //写入f数组 return f[s][e]; //返回 } if(f[s][e] != -1) //不等于-1表示之前已经计算过!所以直接返回 { return f[s][e]; } for(k=s;k<e;k++) //以前没有计算过,那么递归计算,找最小值! { if( min > min_strength(s, k) + min_strength(k+1, e) ) min = min_strength(s, k) + min_strength(k+1, e) ; } min = min + sum(s,e); f[s][e]=min; return min; } main() { int n,i,j,w,v=0;//n为有几堆书本 scanf("%d",&n);//输入有几堆书本 for(i=0;i<n;i++)//输入N堆书 { scanf("%d %d",&w,&v);//用户输入数据 book[i]=w-v; } for(i=0;i<n;i++) //f数组所有元素都赋值-1 for(j=0;j<n;j++) f[i][j]=-1; for(i=0;i<n;i++) //对角线元素为0 f[i][i]=0; strength=min_strength(0,n-1);//求最小力气! print();//打印结果函数 }