题目里讲的是归并。 用递归做
[ 本帖最后由 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();//打印结果函数
}

