您的位置:首页 > 其它

合并果子

2018-02-09 16:10 274 查看
蒜头君很想吃果子,正好果园果子熟了。在果园里,蒜头君已经将所有的果子打了下来,按照就近原则把果子合成了 nn 堆。蒜头君决定把所有的果子合成一堆。 因为蒜头君比较懒,为了省力气,蒜头君开始想点子了:  每一次合并,蒜头君可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过 n-1n−1 次合并之后,就只剩下一堆了。蒜头君在合并果子时总共消耗的体力等于每次合并所耗体力之和。  因为还要花大力气把这些果子搬回家,所以蒜头君在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使蒜头君耗费的体力最少,并输出这个最小的体力耗费值。  例如有 33 堆果子,数目依次为 11,22,99。可以先将 11、22 堆合并,新堆数目为 33,耗费体力为 33。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为 1212,耗费体力为 1212。所以蒜头君总共耗费体力 =3+12=15=3+12=15。可以证明 1515 为最小的体力耗费值。

输入格式

第一行输入一个整数 n(1 \le n \le 10^4)n(1≤n≤104),第二行有 nn 个整数 xx (1 \le x \le 10^4)(1≤x≤104)。

输出格式

输出蒜头君消费的最小体力值。#include <iostream>
#include <algorithm>
#include <cstdio>  
using namespace std;  
int a[10000];
int n;
void dfs(int x){
    int i;
    int t;
    int q;
    q=x;
    for(i=q+1;i<=n;i++){
        if(a[i]<a[q]){
            q=i;
        } 
    }
    swap(a[x],a[q]);  
}
int main(){
    int i;
    int sum;
//取反运算
    while(~scanf("%d",&n)){ 
        //~是位操作运算符&是与运算,a&=~b即 a= a & (~b)
        sum=0;
        for(i=1;i<=n;i++)
            cin>>a[i];
        dfs(1);
        dfs(2);
        for(i=2;i<=n;i++){
            a[i]+=a[i-1];
            sum+=a[i];
            dfs(i);
            dfs(i+1);
        }
       printf("%d\n",sum); 
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: