题目传送门
题意:
给你 个数
,让你选择
个数,问乘积后面最多有几个
。
数据范围: 。
题解:
设乘积的因子中 的个数有
个 ,
的个数有
个。
答案是 。
表示前
个数选择
个数乘积的因子包含
个
的方案包含
的最大个数。
转移方程:。
其中 表示
的因子中
的个数,
表示
的因子中
的个数。
感受:
这题 竟然能
跑完,不知道为什么。
代码:
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
const int maxn = 205 ;
const int maxm = 5305 ;
int n , k ;
ll a[maxn] ;
int dp[maxn][maxm] ;
int main()
{
int cnt = 0 , ans = 0 ;
scanf("%d%d" , &n , &k) ;
for(int i = 1 ; i <= n ; i ++) scanf("%lld" , &a[i]) ;
for(int i = 0 ; i <= 200 ; i ++)
for(int j = 0 ; j <= 5300 ; j ++)
dp[i][j] = -1e9 ;
dp[0][0] = 0 ;
for(int i = 1 ; i <= n ; i ++)
{
int x = 0 , y = 0 ;
while(a[i] % 5 == 0) a[i] /= 5 , x ++ , cnt ++ ;
while(a[i] % 2 == 0) a[i] /= 2 , y ++ ;
for(int j = k ; j > 0 ; j --)
for(int p = x ; p <= cnt ; p ++)
dp[j][p] = max(dp[j][p] , dp[j - 1][p - x] + y) ;
}
for(int i = 1 ; i <= cnt ; i ++)
ans = max(ans , min(i , dp[k][i])) ;
printf("%d\n" , ans) ;
return 0 ;
}