• Codeforces 837D Round Subset


    Let's call the roundness of the number the number of zeros to which it ends.

    You have an array of n numbers. You need to choose a subset of exactly k numbers so that the roundness of the product of the selected numbers will be maximum possible.

    Input

    The first line contains two integer numbers n and k (1 ≤ n ≤ 200, 1 ≤ k ≤ n).

    The second line contains n space-separated integer numbers a1, a2, ..., an (1 ≤ ai ≤ 1018).

    Output

    Print maximal roundness of product of the chosen subset of length k.

    Examples
    Input
    3 2
    50 4 20
    Output
    3
    Input
    5 3
    15 16 3 25 9
    Output
    3
    Input
    3 3
    9 77 13
    Output
    0
    Note

    In the first example there are 3 subsets of 2 numbers. [50, 4] has product 200 with roundness 2, [4, 20] — product 80, roundness 1, [50, 20] — product 1000, roundness 3.

    In the second example subset [15, 16, 25] has product 6000, roundness 3.

    In the third example all subsets has product with roundness 0.


      题目大意 给定一个数组,从中选出k个数(不能选同一个数),使得这k个数的乘积的末尾的零的个数最多。

      根据小学的数学知识,我们知道一个数的末尾有多个零取决于它质因数分解后2的指数和5的指数的最小值。(10 = 2 × 5)

      所以我们初步得到动态规划的状态f[i][j][k]表示,从前i个数中,选出j个数,使得它们的乘积质因数分解后2的指数为k,5的指数最大为多少。

      显然它有两种转移:选第i + 1个数,不选第i + 1个数。所以转移是显然的。

      然后您会得到MLE,所以加上黑科技bfs版 + 滚动数组动态规划,不知道能不能卡过,但是有一种很简单的优化方法。

      显然将题目中输入的一个数质因数分解后5的指数不会超过。所以我们可以把5个个数作为状态,2的个数作为状态的值,这样总状态数不会超过2003 * 25(刚刚是乘64)

      所以继续黑科技优化内存和时间就过了。

    Code

      1 /**
      2  * Codeforces
      3  * Problem#837D
      4  * Accepted
      5  * Time: 187ms
      6  * Memory: 10604k
      7  */
      8 #include <bits/stdc++.h>
      9 using namespace std;
     10 typedef bool boolean;
     11 #define smax(a, b) a = max(a, b);
     12 template<typename T>
     13 inline boolean readInteger(T& u){
     14     char x;
     15     int aFlag = 1;
     16     while(!isdigit((x = getchar())) && x != '-' && x != -1);
     17     if(x == -1) {
     18         ungetc(x, stdin);    
     19         return false;
     20     }
     21     if(x == '-'){
     22         x = getchar();
     23         aFlag = -1;
     24     }
     25     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
     26     ungetc(x, stdin);
     27     u *= aFlag;
     28     return true;
     29 }
     30 
     31 typedef class Status {
     32     public:
     33         int stage;
     34         int seced;
     35         int c5;
     36 }Status;
     37 
     38 int n, k;
     39 int *c2s, *c5s;
     40 int res = 0;
     41 
     42 inline void init() {
     43     long long x;
     44     readInteger(n);
     45     readInteger(k);
     46     c2s = new int[(n + 1)];
     47     c5s = new int[(n + 1)];
     48     for(int i = 1; i <= n; i++) {
     49         c2s[i] = c5s[i] = 0;
     50         readInteger(x);
     51         while(!(x & 1))    x >>= 1, c2s[i]++;
     52         while(!(x % 5))    x /= 5, c5s[i]++;
     53     }
     54 }
     55 
     56 queue<Status> que;
     57 int f[2][201][4001];
     58 inline void dp() {
     59     int last = 0;
     60     Status sta = (Status) {0, 0, 0};
     61     que.push(sta);
     62     memset(f, -1, sizeof(f));
     63     f[0][0][0] = 0;
     64     while(!que.empty()) {
     65         Status e = que.front();
     66         que.pop();
     67         
     68         int lastf = f[e.stage & 1][e.seced][e.c5];
     69         Status eu = e;
     70         eu.stage++;
     71         if(eu.stage != last) {
     72             last = eu.stage;
     73             memset(f[eu.stage & 1], -1, sizeof(f[0]));
     74         }
     75         
     76         if(f[eu.stage & 1][eu.seced][eu.c5] == -1 && eu.stage < n && eu.seced <= k)
     77             que.push(eu);
     78         else if(eu.stage == n && eu.seced == k)
     79             smax(res, min(eu.c5, lastf));
     80         smax(f[eu.stage & 1][eu.seced][eu.c5], lastf);
     81         
     82         eu.seced++, eu.c5 += c5s[eu.stage];
     83         if(f[eu.stage & 1][eu.seced][eu.c5] == -1 && eu.stage < n && eu.seced <= k)
     84             que.push(eu);
     85         else if(eu.stage == n && eu.seced == k)
     86             smax(res, min(eu.c5, lastf + c2s[eu.stage]));
     87         smax(f[eu.stage & 1][eu.seced][eu.c5], lastf + c2s[eu.stage]);
     88     }
     89 }
     90 
     91 inline void solve() {
     92     printf("%d
    ", res);
     93 }
     94 
     95 int main() {
     96     init();
     97     dp();
     98     solve();
     99     return 0;
    100 }
  • 相关阅读:
    jvm性能调优---jstat的用法
    flume-ng+Kafka+Storm+HDFS 实时系统搭建
    proxool
    Shell实现跳板机,为什么用跳板机
    JUC回顾之-ThreadPoolExecutor的原理和使用
    java集合之ArrayList的实现原理
    JMeter性能测试介绍学习一
    基础知识《十三》深入浅出Java回调机制
    怎样将myeclipse里默认编码设置成utf-8
    《转》怎样看待比自己强的人
  • 原文地址:https://www.cnblogs.com/yyf0309/p/7290454.html
Copyright © 2020-2023  润新知