以前做过一个类似的,不过这次的显然范围要比以前那个大得多,不过还是可以用相同的方式去解决。
一开始想的无脑递推是如果i这个已经是humble number了的话,就把humble number的那些素数倍数全部标记为humble number,可是显然这样是不行的。
但是可以反过来处理,用cnt[j]表示乘以素数pri[j]之后不会出现重复数字的最小的humble number的编号,然后每次做更新的时候只要扫一遍所有的pri[j]*num[cnt[j]]找到最小的即可,注意这样扫一遍之后要把所有cnt[j]全部更新一遍以保证不重复出现。
/* ID: flsnnx1 LANG: C++ TASK: humble */ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 100000 + 5; typedef long long LL; int n,k; LL num[maxn]; int pri[maxn]; int cnt[maxn]; void setfile() { freopen("humble.in","r",stdin); freopen("humble.out","w",stdout); } int main() { setfile(); cin >> n >> k; for(int i = 1;i <= n;i++) cin >> pri[i]; for(int i = 1;i <= n;i++) cnt[i] = 1; num[1] = 1; for(int i = 2;i <= k + 2;i++) { LL minval = 1e17; for(int j = 1;j <= n;j++) { int nowval = num[cnt[j]] * pri[j]; if(nowval < minval) { minval = nowval; } } for(int j = 1;j <= n;j++) { if(num[cnt[j]] * pri[j] == minval) cnt[j]++; } num[i] = minval; } cout << num[k + 1] << endl; return 0; }