程序代码:
/***********************************************************/
/**小弟学C不久...所以写的东西比较浅显,见谅见谅,呵呵.******/
/**下面是自己写的关于这个题目的算法,望高手们指教。谢谢!****/
/***********************************************************/
#include<stdlib.h>
#include<stdio.h>
void main()
{
int i,j,n,k,*stone;
printf("请输入石堆数:");
scanf("%d",&n);
printf("请输入可合并的最大堆数:");
scanf("%d",&k);
printf("\n");
stone=(int *)calloc(n,sizeof(int)); //开辟放置石子的内存。
if(stone==NULL)
{
printf("内存分配失败!\n");
exit(0);
}
else
for(i=1;i<=n;i++)
{
printf("请输入第%2d堆的石子数:",i); //输入每堆的石子数。
scanf("%d",stone+i-1);
}
int temp;
for(i=0;i<n;i++) //从小到大排序。
for(j=i+1;j<n;j++)
if( *(stone+i) > *(stone+j) )
{
temp=*(stone+i);
*(stone+i)=*(stone+j);
*(stone+j)=temp;
}
for(i=0;i<n;i++)
{
if(!(i%5))
printf("\n"); //每输出5个空行。
printf("%d\t",*(stone+i)); //演示排序后结果。
}
int max=0; //求出最大费用。
for(i=1;i<=n;i++)
max+=i*(*(stone+i-1)); //(思路为每次选择最大的两个值相加,
max-=(*(stone+n-1));
printf("\n\n最大费用为:%d;\n",max); //很容易知道每个数被加了多少次)。
int min=0; //求出最小费用。
while(n>k)
{
n-=k;
temp=0;
for(i=0;i<k;i++) //单次选择的k个最小的数。
temp+=*(stone+i);
min+=temp; //min每次自加上。
for(i=0;i<n;i++)
*(stone+i)=*(stone+i+k); //选择过的石子堆没用了,用后面没选择的一次顶上。
for(i=0;i<n;i++)
if(temp<*(stone+i)) //将刚才合并的那个石子堆插入其中。
{
for(j=n;j>i;j--)
*(stone+j)=*(stone+j-1);
*(stone+i)=temp;
break;
}
if(temp>*(stone+n)) //刚才合并的石子堆可能是最大的。
*(stone+n)=temp; //这时就放在最后面。
n++; //这个要自己想下,每次合并后
} //其实减少的堆数是k-1;
for(i=0;i<n;i++)
min+=*(stone+i); //将剩余不足k堆的加起来。
printf("最小费用为:%d.\n\n",min);
}
呵呵