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.
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).
Print maximal roundness of product of the chosen subset of length k.
3 2
50 4 20
3
5 3
15 16 3 25 9
3
3 3
9 77 13
0
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
/**
* Codeforces
* Problem#837D
* Accepted
* Time: 187ms
* Memory: 10604k
*/
#include <bits/stdc++.h>
using namespace std;
typedef bool boolean;
#define smax(a, b) a = max(a, b);
template<typename T>
inline boolean readInteger(T& u){
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-' && x != -);
if(x == -) {
ungetc(x, stdin);
return false;
}
if(x == '-'){
x = getchar();
aFlag = -;
}
for(u = x - ''; isdigit((x = getchar())); u = (u << ) + (u << ) + x - '');
ungetc(x, stdin);
u *= aFlag;
return true;
} typedef class Status {
public:
int stage;
int seced;
int c5;
}Status; int n, k;
int *c2s, *c5s;
int res = ; inline void init() {
long long x;
readInteger(n);
readInteger(k);
c2s = new int[(n + )];
c5s = new int[(n + )];
for(int i = ; i <= n; i++) {
c2s[i] = c5s[i] = ;
readInteger(x);
while(!(x & )) x >>= , c2s[i]++;
while(!(x % )) x /= , c5s[i]++;
}
} queue<Status> que;
int f[][][];
inline void dp() {
int last = ;
Status sta = (Status) {, , };
que.push(sta);
memset(f, -, sizeof(f));
f[][][] = ;
while(!que.empty()) {
Status e = que.front();
que.pop(); int lastf = f[e.stage & ][e.seced][e.c5];
Status eu = e;
eu.stage++;
if(eu.stage != last) {
last = eu.stage;
memset(f[eu.stage & ], -, sizeof(f[]));
} if(f[eu.stage & ][eu.seced][eu.c5] == - && eu.stage < n && eu.seced <= k)
que.push(eu);
else if(eu.stage == n && eu.seced == k)
smax(res, min(eu.c5, lastf));
smax(f[eu.stage & ][eu.seced][eu.c5], lastf); eu.seced++, eu.c5 += c5s[eu.stage];
if(f[eu.stage & ][eu.seced][eu.c5] == - && eu.stage < n && eu.seced <= k)
que.push(eu);
else if(eu.stage == n && eu.seced == k)
smax(res, min(eu.c5, lastf + c2s[eu.stage]));
smax(f[eu.stage & ][eu.seced][eu.c5], lastf + c2s[eu.stage]);
}
} inline void solve() {
printf("%d\n", res);
} int main() {
init();
dp();
solve();
return ;
}
Codeforces 837D Round Subset - 动态规划 - 数论的更多相关文章
- CodeForces 837D - Round Subset | Educational Codeforces Round 26
/* CodeForces 837D - Round Subset [ DP ] | Educational Codeforces Round 26 题意: 选k个数相乘让末尾0最多 分析: 第i个数 ...
- Codeforces 837D - Round Subset(dp)
837D - Round Subset 思路:dp.0是由2*5产生的. ①dp[i][j]表示选i个数,因子2的个数为j时因子5的个数. 状态转移方程:dp[i][j]=max(dp[i][j],d ...
- Codeforces 837D Round Subset(背包)
题目链接 Round Subset 题意 在n个数中选择k个数,求这k个数乘积末尾0个数的最大值. 首先我们预处理出每个数5的因子个数c[i]和2的因子个数d[i] 然后就可以背包了. 设f[i] ...
- Codeforces 837D - Round Subset DP
先算出每个数的pop1(twonum),pop(fivenum)然后DP ans[i][j]表示选i个数有j个2时最多有多少个5 转移方程是 ;j--) { ;w++) { ans[j][w]=max ...
- CF837D Round Subset 动态规划
开始的时候数据范围算错了~ 我以为整个序列 2 和 5 的个数都不超过 70 ~ 一个非常水的 dp code: #include <bits/stdc++.h> #define M 75 ...
- Educational Codeforces Round 26 [ D. Round Subset ] [ E. Vasya's Function ] [ F. Prefix Sums ]
PROBLEM D - Round Subset 题 OvO http://codeforces.com/contest/837/problem/D 837D 解 DP, dp[i][j]代表已经选择 ...
- Codeforces Global Round 1 - D. Jongmah(动态规划)
Problem Codeforces Global Round 1 - D. Jongmah Time Limit: 3000 mSec Problem Description Input Out ...
- Codeforces Beta Round #17 D. Notepad (数论 + 广义欧拉定理降幂)
Codeforces Beta Round #17 题目链接:点击我打开题目链接 大概题意: 给你 \(b\),\(n\),\(c\). 让你求:\((b)^{n-1}*(b-1)\%c\). \(2 ...
- Codeforces 837D 动态规划
Codeforces 837D 动态规划 传送门:https://codeforces.com/contest/837/problem/D 题意: 给你n个数,问你从这n个数中取出k个数,这k个数的乘 ...
随机推荐
- 从零开始一起学习SLAM | 为什么要学SLAM?
在<零基础小白,如何入门计算机视觉?>中我提到过,计算机视觉的研究目前主要分为两大方向:基于学习的方法和基于几何的方法.其中基于学习的方法最火的就是深度学习,而基于几何方法最火的就是视觉S ...
- Linux基础(六) Vim之vundle插件
背景 Vim缺乏默认的插件管理器,所有插件的文件都散布在~/.vim下的几个文件夹中,插件的安装与更新与删除都需要自己手动来,既麻烦费事,又可能出现错误. Vundle简介 Vundle 是 Vim ...
- is_readable() 函数检查指定的文件是否可读。
定义和用法 is_readable() 函数判断指定文件名是否可读. 语法 is_readable(file) 参数 描述 file 必需.规定要检查的文件. 说明 如果由 file 指定的文件或目录 ...
- VS.C#如何向数据数据库中存入和读取图片的
写入图片部分代码:假设图片为 test.gifbyte [] bytes = File.ReadAllBytes(@"c:\test.gif");SqlConnection con ...
- Nginx常用功能
3.Nginx常用功能 3.1 反向代理服务器 3.1.1.demo2 a.我在tomcat下部署了一个javaweb项目,tomcat安装的服务器IP为:192.168.37.136,部署的项目在t ...
- HDU 6298
Problem Description Given an integer n, Chiaki would like to find three positive integers x, y and z ...
- 【转】win中IDLE选择virtualenv的启动方法
从dos命令行运行.(virtualenv dir)\Scripts\activate.bat脚本激活环境,然后执行: python -m idlelib.idle 摘录:https://blog.c ...
- 网关绑定命令,解决arp攻击
一般家里的宽带都采用ADSL设备,通过固定IP地址接入Internet,但是经常会出现断网的现象,那么如何通过ARP命令绑定默认网关来解决这个问题呢? 工具/原料 ARP命令 CMD命令提示符 方法/ ...
- python中装饰器修复技术
python装饰器@wraps作用-修复被装饰后的函数名等属性的改变 Python装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变), 为了 ...
- python 将一个JSON 字典转换为一个Python 对象
将一个JSON 字典转换为一个Python 对象例子 >>> s='{"name":"apple","shares":50 ...