本文主要是介绍cf Educational Codeforces Round 26 D. Round Subset,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
原题:
D. Round Subset
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
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.
中文:
给你n个数,让你选k个相乘。问你最后末尾0的个数最多有多少个。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
ll n,k;
ll dp[201][10001];
ll two[201],five[201],num[201];
pii get_five_two(ll x)
{int f=0,t=0;while(true){if(x%5)break;x/=5;f++;}while(true){if(x%2)break;x/=2;t++;}return make_pair(f,t);
}int main()
{ios::sync_with_stdio(false);while(cin>>n>>k){ll tot=0;for(int i=1;i<=n;i++){cin>>num[i];pii p=get_five_two(num[i]);two[i]=p.second;five[i]=p.first;tot+=five[i];}for(int i=0;i<=200;i++){for(int j=0;j<=10000;j++)dp[i][j]=INT_MIN;}dp[0][0]=0;for(ll i=1;i<=n;i++){for(ll j=min(i,k);j>=1;j--){for(ll kk=tot;kk>=five[i];kk--)dp[j][kk]=max(dp[j][kk],dp[j-1][kk-five[i]]+two[i]);}}ll ans=0;for(ll i=1;i<=tot;i++)ans=max(ans,min(dp[k][i],i));//5和2最小的cout<<ans<<endl;}return 0;
}
解答:
出现0的只有2和5相乘才可以,所以n个数,每个数都记录有多少个2因子和5因子。
n个数选k个,明显的背包问题。如果直接套用01背包模型在状态转移的时候无法得知上一个状态2和5的个数。
增加一维,记录5的个数(2也可以)。设置状态转移方程
dp[i][j][k]=max(dp[[i−1][j][k],dp[i−1][j−1][k−five[i]]+two[i])
表示前i个数选j个能有k个5的情况下,最多能有多少个2。
那么最后结果找出选k个数的情况下,2和5最少的那个就是0的个数
注意使用滚动数组,变成2维,否则爆内存
dp[j][k]=max(dp[j][k],dp[j−1][k−five[i]]+two[i])
这篇关于cf Educational Codeforces Round 26 D. Round Subset的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!