
程序代码:
/***********************************************************/
/**小弟学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);
}
 呵呵
呵呵