题解

535 条题解

  • 0
    @ 2014-08-12 15:59:13

    根本就不用排序,其实就是个贪心。
    每次找最小的两堆合并就可以啦。

    {真不懂某些人只发个代码出来干什么?又没人看,浪费空间}

    • @ 2015-02-27 17:11:50

      同意你 { } 里的内容

  • 0
    @ 2014-07-18 16:53:51

    #include<cstdio>
    #include<queue>
    using namespace std;
    #define IOFileName "P1097"
    int n,ai,x,y,ans=0;
    priority_queue<int,deque<int>,greater<int> >a;
    int main(){
    freopen(IOFileName".in","r",stdin);
    freopen(IOFileName".out","w",stdout);
    scanf("%d\n",&n);
    for(int i=0;i<n;i++){
    scanf("%d ",&ai);
    a.push(ai);
    }
    while(a.size()>1){
    x=a.top();a.pop();
    y=a.top();a.pop();
    a.push(x+y);
    ans+=x+y;
    }
    printf("%d\n",ans);
    }
    90MS+276KB

  • 0
    @ 2014-05-16 15:32:46

    #include<iostream>
    #include<iomanip>
    #include<string>
    #include<algorithm>
    #include<ctime>
    using namespace std;

    int a[10010];
    void qsort(int l,int r)
    {
    int i,j,mid,p;
    i=l;
    j=r;
    mid=a[(l+r)/2];
    while(i<=j)
    {
    while(a[i]<mid) i++;
    while(a[j]>mid) j--;
    if(i<=j)
    {
    p=a[i];
    a[i]=a[j];
    a[j]=p;
    i++;
    j--;

    }

    }
    if(l<j) qsort(l,j);
    if(i<r) qsort(i,r);
    }
    int main()
    {
    int n,e=0,y=0;
    cin>>n;
    for(int i=1;i<=n;i++)
    cin>>a[i];

    qsort(1,n);
    for(int i=2;i<=n;i++)
    {
    a[i]=a[i]+a[i-1];
    e=e+a[i];

    int q=a[i];
    for(int j=i;j<=n;j++)
    {
    if(a[j]<=a[i]&&a[j+1]>=a[i]||a[j]<a[i]&&j==n)
    {
    y=1;
    for(int o=i;o<=j-1;o++)
    {
    a[o]=a[o+1];

    }
    a[j]=q;
    }

    if(y==1) break;

    }

    y=0;
    }
    cout<<e;

    return 0;

    }

  • 0
    @ 2014-05-16 15:32:05

    #include<iostream>
    using namespace std;

    int heap[20010];
    void heapdown(int i,int n)
    {
    int j;
    j=i*2;
    while(j<=n)
    {
    if(j<n&&heap[j+1]<heap[j]) j++;
    if(heap[i]<=heap[j]) break;
    swap(heap[i],heap[j]);
    i=j;
    j=i*2;
    }
    }
    int main()
    {
    int n,k,l,ans=0;
    cin>>n;
    for(int i=1;i<=n;i++)
    cin>>heap[i];
    for(int i=n;i>=1;i--)
    heapdown(i,n);
    for(int i=1;i<n;)
    {
    k=heap[1]+heap[2];
    l=heap[1]+heap[3];
    if(k<l)
    {

    heap[2]=k;
    ans=ans+k;
    heap[1]=heap[n];
    n--;
    heapdown(2,n);
    heapdown(1,n);
    }

    else
    {
    heap[3]=l;
    ans=ans+l;
    heap[1]=heap[n];
    n--;
    heapdown(3,n);
    heapdown(1,n);
    }

    }
    cout<<ans<<endl;

    return 0;

    }

  • 0
    @ 2014-05-13 22:11:52

    int main()
    {
    int x,N,goup[10000],i,n,j,t,sum=0;
    scanf("%d",&N);
    for(i=0;i<N;i++)
    scanf("%d",&goup[i]);
    for(i=0;i<N-1;i++)
    { n=i;
    for(j=i+1;j<N;j++)
    {if(goup[n] > goup[j]) n=j;}
    t=goup[i];goup[i]=goup[n];goup[n]=t;}
    for(i=0;i<N-1;i++)
    {goup[i+1]=goup[i]+goup[i+1];
    sum=sum+goup[i+1];
    for(x=i+1;x<i+3;x++)
    {n=x;
    for(j=x+1;j<N;j++)
    {if(goup[n]>goup[j])n=j;}
    t=goup[x];goup[x]=goup[n];goup[n]=t;} }
    if(N>2)printf("%d",sum);
    if(N==1)printf("%d",goup[0]);
    if(N==2)printf("%d",goup[0]+goup[1]);
    }

    优于快排的算法

  • 0
    @ 2014-05-13 22:10:40

    #include<stdio.h>
    int main()
    {
    int x,N,goup[10000],i,n,j,t,sum=0;
    scanf("%d",&N);
    for(i=0;i<N;i++)
    scanf("%d",&goup[i]);

    for(i=0;i<N-1;i++)
    {
    n=i;
    for(j=i+1;j<N;j++)
    {if(goup[n] > goup[j]) n=j;}
    t=goup[i];goup[i]=goup[n];goup[n]=t;}

    for(i=0;i<N-1;i++)
    {goup[i+1]=goup[i]+goup[i+1];
    sum=sum+goup[i+1];
    for(x=i+1;x<i+3;x++)
    {n=x;
    for(j=x+1;j<N;j++)
    {if(goup[n]>goup[j])n=j;}
    t=goup[x];goup[x]=goup[n];goup[n]=t;}
    }
    if(N>2)printf("%d",sum);
    if(N==1)printf("%d",goup[0]);
    if(N==2)printf("%d",goup[0]+goup[1]);
    }

    优于快排的算法

  • 0
    @ 2014-01-25 18:11:39

    program fruit;
    var i:longint;
    mindui:array[0..100100] of int64;
    frut,duia,duib,size,s,n:int64;
    procedure huan(var a,b:int64);
    var m:int64;
    begin
    m:=a;
    a:=b;
    b:=m;
    end;
    procedure up(var a:int64);
    var fa:int64;
    begin
    if a=1 then exit;
    fa:=a div 2;
    if mindui[fa]<=mindui[a] then exit;
    huan(mindui[fa],mindui[a]);
    up(fa);
    end;
    procedure down( a:int64);
    var son:int64;
    begin
    son:=2*a;
    if son>size then exit;
    if (son+1<=size)and(mindui[son]>mindui[son+1])
    then inc(son);
    if mindui[son]>=mindui[a]
    then exit;
    huan(mindui[son],mindui[a]);
    down(son);
    end;
    begin
    readln(n);size:=0;s:=0;
    for i:=1 to n do
    begin
    read(frut);
    inc(size);
    mindui[size]:=frut;
    up(size);
    end;
    for i:=1 to n-1 do
    begin
    duia:=mindui[1];
    mindui[1]:=mindui[size];
    dec(size);
    down(1);
    duib:=mindui[1];
    mindui[1]:=mindui[size];
    dec(size);
    down(1);
    s:=s+duia+duib;
    inc(size);
    mindui[size]:=duia+duib;
    up(size);
    end;
    writeln(s);
    end.

  • 0
    @ 2014-01-15 15:01:40

    帮我看看哪里错了

    测试数据 #0: TimeLimitExceeded, time = 1015 ms, mem = 1132 KiB, score = 0

    测试数据 #1: Accepted, time = 0 ms, mem = 1132 KiB, score = 10

    测试数据 #2: WrongAnswer, time = 15 ms, mem = 1132 KiB, score = 0

    测试数据 #3: WrongAnswer, time = 31 ms, mem = 1128 KiB, score = 0

    测试数据 #4: WrongAnswer, time = 343 ms, mem = 1132 KiB, score = 0

    测试数据 #5: WrongAnswer, time = 671 ms, mem = 1132 KiB, score = 0

    测试数据 #6: TimeLimitExceeded, time = 1015 ms, mem = 1136 KiB, score = 0

    测试数据 #7: TimeLimitExceeded, time = 1015 ms, mem = 1132 KiB, score = 0

    测试数据 #8: TimeLimitExceeded, time = 1015 ms, mem = 1128 KiB, score = 0

    测试数据 #9: TimeLimitExceeded, time = 1015 ms, mem = 1132 KiB, score = 0
    var b,i,j,m,n:integer;
    a:array[0..200000]of integer;
    procedure sort(l,r: longint);
    var i,j,x,y: longint;
    begin
    i:=l;
    j:=r;
    x:=a[(l+r) div 2];
    repeat
    while a[i]>x do
    inc(i);
    while x>a[j] do
    dec(j);
    if not(i>j) then
    begin
    y:=a[i];
    a[i]:=a[j];
    a[j]:=y;
    inc(i);
    j:=j-1;
    end;
    until i>j;
    if l<j then
    sort(l,j);
    if i<r then
    sort(i,r);
    end;
    begin
    read(n);
    for i:=1 to n do
    read(a[i]);
    m:=n;
    for j:=1 to m-1 do
    begin
    sort(1,n);
    a[n-1]:=a[n-1]+a[n];
    b:=b+a[n-1];
    n:=n-1;
    end;
    writeln(b);
    end.

  • 0
    @ 2014-01-01 11:59:44

    Vijos 题解:http://hi.baidu.com/umule/item/2c997f8ed9600fdae596e017
    有疑问请留言 共同进步

  • 0
    @ 2013-11-07 15:18:02

    这题队列的数组记得要使用Longint,否则就会30分。

  • 0
    @ 2013-11-07 15:17:35

    最简单的方法是使用优先队列,那个会自动管理当前优先级最高的元素

  • 0
    @ 2013-11-07 15:17:03

    最小的最早合并

  • 0
    @ 2013-11-05 20:25:11

    //stl碉堡了。。。。

    #include<cstdio>
    #include<cstring>
    #include<queue>

    int main(){
    int n,tmp,ans=0;
    std::priority_queue<int> q;
    scanf("%d\n",&n);
    for (int i=1;i<=n;i++){
    scanf("%d",&tmp);
    q.push(-tmp);
    }
    for (int i=1;i<n;i++){
    tmp=q.top();q.pop();
    tmp+=q.top();q.pop();
    q.push(tmp);
    ans-=tmp;
    }
    printf("%d\n",ans);
    return 0;
    }

  • 0
    @ 2013-10-20 21:04:28

    var
    a:array[0..10000]of longint;
    m,n,x,ans,i:longint;
    procedure down(i:longint);
    var
    x,j:longint;
    begin
    while i*2<=n do
    begin
    j:=i*2;
    if 2*i+1<=n then if a[j]>a[j+1] then j:=j+1;
    if a[j]<a[i] then
    begin
    x:=a[j];
    a[j]:=a[i];
    a[i]:=x;
    end else break;
    i:=j;
    end;
    end;
    begin
    //assign(input,'a1.in'); reset(input);
    readln(n);
    for i:=1 to n do read(a[i]);
    for i:=n div 2 downto 1 do down(i);
    m:=n;
    ans:=0;
    for i:=1 to m-1 do
    begin
    x:=a[1];
    a[1]:=a[n];
    dec(n);
    down(1);
    inc(ans,x+a[1]);
    a[1]:=a[1]+x;
    down(1);
    end;
    writeln(ans);
    end.
    为什么楼下的堆排们代码如此长?

  • 0
    @ 2013-08-27 08:21:50

    测试数据 #0: Accepted, time = 0 ms, mem = 852 KiB, score = 10
    测试数据 #1: Accepted, time = 0 ms, mem = 848 KiB, score = 10
    测试数据 #2: Accepted, time = 0 ms, mem = 848 KiB, score = 10
    测试数据 #3: Accepted, time = 0 ms, mem = 852 KiB, score = 10
    测试数据 #4: Accepted, time = 0 ms, mem = 848 KiB, score = 10
    测试数据 #5: Accepted, time = 0 ms, mem = 848 KiB, score = 10
    测试数据 #6: Accepted, time = 0 ms, mem = 848 KiB, score = 10
    测试数据 #7: Accepted, time = 0 ms, mem = 848 KiB, score = 10
    测试数据 #8: Accepted, time = 0 ms, mem = 848 KiB, score = 10
    测试数据 #9: Accepted, time = 0 ms, mem = 848 KiB, score = 10
    Accepted, time = 0 ms, mem = 852 KiB, score = 100
    运用堆排序,0ms秒过

    program fruit;
    var
    heap : array[1..30000] of longint;
    ans,n,i,tmp,a,b,len : longint;
    procedure put(x:longint);
    var
    fa,son,tmp : longint;
    begin
    len := len + 1;
    heap[len] := x;
    son := len;
    while (son <> 1) and (heap[son div 2]>heap[son]) do
    begin
    tmp := heap[son div 2];
    heap[son div 2] := heap[son];
    heap[son] := tmp;
    son := son div 2;
    end;
    end;
    function get : longint;
    var
    fa,son,tmp : longint;
    stop : boolean;
    begin
    get := heap[1];
    heap[1] := heap[len];
    dec(len);
    fa := 1;
    stop := false;
    while ((fa * 2 <= len) or (fa * 2 + 1 <= len)) and (not stop) do
    begin
    if (fa * 2 + 1 > len) or (heap[fa * 2]<heap[fa * 2+1]) then son := fa * 2 else son := fa * 2 + 1;
    if heap[fa] > heap[son] then begin
    tmp := heap[fa];
    heap[fa] := heap[son];
    heap[son] := tmp;
    fa := son;
    end else stop := true;
    end;
    end;
    begin
    //assign(input,'fruit.in');
    //assign(output,'fruit.out');
    reset(input);
    rewrite(output);
    len := 0;
    readln(n);
    for i := 1 to n do
    begin
    read(tmp);put(tmp);
    end;
    ans := 0;
    for i := 1 to n - 1 do
    begin
    a := get;b := get;
    ans := ans + a + b;
    put(a+b);
    end;
    writeln(ans);
    // close(input);
    //close(output);
    end.

  • 0
    @ 2013-08-16 22:00:35

    贪心

    最小的最早合并

    证明

    1. 第i次合并的果子从头至尾共消耗的力气是*(n-i+1)*weight* (weight是该堆果子的重量)
    2. 所以合并n堆的果子的序列如果是(b1,b2,b3,b4……,bn),则总消耗体力 n*weight[b1]+(n-1)*weight[b2]+(n-2)*weight[b3]+...+1*weight[bn]
    3. 由此,大家可以很容易的看出重量最小的应当最先合并。
    4. 只需先从小到大排序,然后大家应该清楚该怎么做了。 代码我就留给大家自行完成了。
  • 0
    @ 2013-08-14 13:17:57

    #include<iostream>
    using namespace std;

    long long a[10001],f[10001][10001],b[10001],r,c;

    void jd(int x,int y)
    {
    int i=x;

    while(i*2<=y)
    {
    int k=2*i;

    if (k+1<=y)
    if (a[k]>a[k+1]) k++;

    if (a[k]<a[i])
    {
    swap(a[k],a[i]);
    i=k;
    }

    else return;

    }

    }

    int main()
    {
    int i,j,n,k,t,a1,a2;
    cin>>n;

    for(i=1;i<=n;i++)
    cin>>a[i];

    for(i=n/2;i>=1;i--) jd(i,n);

    int d=0;

    for(int i=1;i<=n-1;i++)
    {
    a1=a[1];
    a[1]=a[n-i+1];
    jd(1,n-i);

    a2=a[1];
    t=a1+a2;
    d=d+t;
    a[1]=t;
    jd(1,n-i);

    }

    cout<<d;

    return 0;
    }

  • 0
    @ 2013-08-14 13:17:06

    堆排秒杀

  • 0
    @ 2013-08-13 19:35:24

    o( ̄▽ ̄)o 水过~~~~
    Var n,i,j,total,ans,tmp1,tmp2,y:longint;
    a:array[1..50000] of longint;
    Procedure down(i:longint);
    Var j,y:longint;
    Begin
    While i*2<=total Do
    Begin
    j:=i*2;
    If (a[j]>a[j+1]) and (j<total) then inc(j);
    If a[j]<a[i] then
    Begin
    y:=a[i];
    a[i]:=a[j];
    a[j]:=y;
    i:=j;
    End
    Else break;
    End;
    End;
    Begin
    assign(input,'input.txt');
    reset(input);
    Readln(n);
    total:=n;
    For i:=1 to n do read(a[i]);
    For i:=n div 2 downto 1 do down(i);
    While total<>1 do
    Begin
    tmp1:=a[1];
    y:=a[1];
    a[1]:=a[total];
    a[total]:=y;
    dec(total);
    down(1);
    tmp2:=a[1];
    a[1]:=tmp2+tmp1;
    ans:=ans+tmp1+tmp2;
    down(1);
    End;
    writeln(ans);
    readln;
    End.

    =皿= 为毛好好的代码都要左对齐!

  • 0
    @ 2013-08-02 22:59:37

    快排

信息

ID
1097
难度
6
分类
贪心 点击显示
标签
递交数
23906
已通过
6330
通过率
26%
被复制
41
上传者