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 250 4 20

Output

3

Input

5 315 16 3 25 9

Output

3

Input

3 39 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\n", res);
 93 }
 94
 95 int main() {
 96     init();
 97     dp();
 98     solve();
 99     return 0;
100 }
时间: 2024-10-02 09:50:51

Codeforces 837D Round Subset - 动态规划 - 数论的相关文章

Codeforces 837D Round Subset(背包)

题目链接  Round Subset 题意  在n个数中选择k个数,求这k个数乘积末尾0个数的最大值. 首先我们预处理出每个数5的因子个数c[i]和2的因子个数d[i] 然后就可以背包了. 设f[i][j]为选i个数,5的因子总和为j时,2的因子总和的最大值. 则状态转移方程为 $f[i][j] = max(f[i - 1][j - c[k]] + d[k])$ 注意边界条件 时间复杂度$O(5200nk)$ #include <bits/stdc++.h> using namespace s

Codeforces 837D - Round Subset DP

先算出每个数的pop1(twonum),pop(fivenum)然后DP ans[i][j]表示选i个数有j个2时最多有多少个5 转移方程是 for(int j=k;j>=1;j--) { for(int w=pop1;w<5000;w++) { ans[j][w]=max(ans[j][w],ans[j-1][w-pop1]+pop); } } AC程序: #include <bits/stdc++.h> #include <cstring> #include <

Educational Codeforces Round 26 D. Round Subset 动态规划

D. 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

Educational Codeforces Round 26 D. Round Subset(dp)

题目链接:Educational Codeforces Round 26 D. Round Subset 题意: 给你n个数,让你选其中的k个数,使得这k个数的乘积的末尾的0的个数最大. 题解: 显然,末尾乘积0的个数和因子2和因子5的个数有关. 然后考虑dp[i][j]表示选i个数,当前因子5的个数为j时,能得到因子2最多的为多少. 那么对于每个数,记录一下因子2和5的个数,做一些01背包就行了. 1 #include<bits/stdc++.h> 2 #define mst(a,b) me

【动态规划】Round Subset

CF837D. 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 ma

[CodeForces - 1225D]Power Products 【数论】 【分解质因数】

[CodeForces - 1225D]Power Products [数论] [分解质因数] 题目描述 Time limit 2000 ms Memory limit 524288 kB Source Technocup 2020 - Elimination Round 2 Tags hashing math number theory *1900 Site https://codeforces.com/problemset/problem/1225/D 题面 Example Input 6

Codeforces Beta Round #91 (Div. 1 Only) E. Lucky Array

E. Lucky Array Petya loves lucky numbers. Everybody knows that lucky numbers are positive integers whose decimal representation contains only the lucky digits 4 and 7. For example, numbers 47, 744, 4 are lucky and 5, 17, 467are not. Petya has an arra

Codeforces Beta Round #85 (Div. 1 Only) C (状态压缩或是数学?)

C. Petya and Spiders Little Petya loves training spiders. Petya has a board n × m in size. Each cell of the board initially has a spider sitting on it. After one second Petya chooses a certain action for each spider, and all of them humbly perform it

CodeForces Beta Round #1

Codeforces Beta Round #1 A. Theatre Square [题意]一个n*m的矩形广场,用a*a的方形石板铺设,问最少需要多少块石板能铺满广场. [思路]水题,从n方向来看能能够铺设ceil(n/a)块,从m方向来看能能够铺设ceil(m/a)块,总共有ceil(n/a)*ceil(m/a)块. 1 /* 2 ** CodeForces 1A Theatre Square 3 ** Created by Rayn @@ 2014/05/18 4 */ 5 #inclu