zoukankan      html  css  js  c++  java
  • Naughty Stone Piles

    题目:http://codeforces.com/problemset/problem/227/D

    题意:n堆个数石子,每堆石子有ai个,通过合并(即将一堆石子移到另一堆石子上),将所有石子合并为一堆,每次合并的代价是这堆石子的个数,在ki的限制下,每堆石子最多只能被合并k次,k次之后就必须移动该堆石子到别的堆上,求合并到最后的总的最小代价。

    题解:emmmmm,既然是找最小代价,那么石子个数最多的那堆石子肯定是不移动的,把个数次小的k堆石子移动到这堆石子上,所以这k堆石子移动了一次,这k堆石子中的每一个又是比他们小的k堆石子合并到它们身上的,即这k*k堆移动了两次,以此类推:

    k                 1次

    k*k              2次

    k*k*k           3次

    k*k*k*k        4次

             .

             .       

             .

             .

    所以总代价最小即是k*1*个数+k^2*2*个数+k^3*3*个数.....

    当然k为1时需要特判,最小堆移动了n-1次,次小堆移动n-2次,最大堆不动,具体看代码。

    注意大部分数据都是long long 范围。

     1 #include <map>
     2 #include <stack>
     3 #include <queue>
     4 #include <cmath>
     5 #include <string>
     6 #include <limits>
     7 #include <cstdio>
     8 #include <vector>
     9 #include <cstdlib>
    10 #include <cstring>
    11 #include <iostream>
    12 #include <algorithm>
    13 #define Scc(c) scanf("%c",&c)
    14 #define Scs(s) scanf("%s",s)
    15 #define Sci(x) scanf("%d",&x)
    16 #define Sci2(x, y) scanf("%d%d",&x,&y)
    17 #define Sci3(x, y, z) scanf("%d%d%d",&x,&y,&z)
    18 #define Scl(x) scanf("%I64d",&x)
    19 #define Scl2(x, y) scanf("%I64d%I64d",&x,&y)
    20 #define Scl3(x, y, z) scanf("%I64d%I64d%I64d",&x,&y,&z)
    21 #define Pri(x) printf("%d
    ",x)
    22 #define Prl(x) printf("%I64d
    ",x)
    23 #define Prc(c) printf("%c
    ",c)
    24 #define Prs(s) printf("%s
    ",s)
    25 #define For(i,x,y) for(int i=x;i<y;i++)
    26 #define For_(i,x,y) for(int i=x;i<=y;i++)
    27 #define FFor(i,x,y) for(int i=x;i>y;i--)
    28 #define FFor_(i,x,y) for(int i=x;i>=y;i--)
    29 #define Mem(f, x) memset(f,x,sizeof(f))
    30 #define LL long long
    31 #define ULL unsigned long long
    32 #define MAXSIZE 100005
    33 #define INF 0x3f3f3f3f
    34 const int mod=1e9+7;
    35 const double PI = acos(-1.0);
    36 
    37 using namespace std;
    38 int cmp(LL a,LL b)
    39 {
    40     return a<b;
    41 }
    42 int main()
    43 {
    44 
    45     LL n;
    46     Scl(n);
    47     int i;
    48     LL a[MAXSIZE]= {0};
    49     for (i=1; i<=n; i++)
    50         Scl(a[i]);
    51     sort(a+1,a+1+n);
    52     LL  tmp=0;
    53     For_(i,1,n-1)//注意这两个for循环的先后顺序
    54     tmp+=a[i]*(n-i);
    55     For_(i,1,n)
    56     a[i]+=a[i-1];//用来计算每隔k的x次方堆石子被合并的次数是相同的,即(a[m]-a[m-k])*cnt,
    57     int q;
    58     Sci(q);
    59     while(q--)
    60     {
    61         LL ans=0;
    62         LL k;
    63         Scl(k);
    64         int t=k;
    65         LL cnt=1,m=n-1;
    66         if(k!=1)
    67         {
    68             while(m>=k)//当k大于等于n时,不执行,直接执行 ans+=cnt*a[m];,即最小代价是前n-1堆石子个数和,即1*a[m].
    69             {
    70                 ans+=(a[m]-a[m-k])*cnt;
    71                 cnt++;
    72                 m-=k;
    73                 k=k*t;//k的变化是k k^2 k^3 k^4...每次乘以最初的k的大小,刚开始写成k*=k,wa一下午,我太难了QAQ
    74             }
    75             ans+=cnt*a[m];
    76         }
    77         else
    78             ans=tmp;
    79         printf("%I64d ",ans);//还有这个谜之输出。
    80     }
    81     return 0;
    82 }
    View Code

     嗯,本来不是难题,硬是用了我一天的时间,真是。。。。。。多个地方都有出过问题。唉。

  • 相关阅读:
    【理财启蒙】理财:需要树立正确的金钱观
    【系统设计】分布式唯一ID生成方案总结
    【Hash一致性算法】什么是Hash一致性算法
    【位图算法】什么是BitMap
    关于枚举类你可能不知道的事
    【数据结构】什么是AVL树
    mysql5.6 主从同步配置
    vmstat命令详解
    pstack跟踪进程栈
    iostat 磁盘io分析工具
  • 原文地址:https://www.cnblogs.com/hbhdhd/p/11413957.html
Copyright © 2011-2022 走看看