L - Clock Master ###K //K
题目链接:https://vjudge.net/contest/408015#problem/L
题意:选多个和不超过b的数 使得其公倍数最大
思路:分组背包问题 分组背包的 v要放在 遍历某一组的物品 之外 才能保证同一组的物品只取一次
模拟一下就可以发现 只需要对质数的正整数幂 分组 即可 注意的是取对数也有复杂度logn
应该用一个数组预处理下 其实质数筛到1000就能过了
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define pb push_back 5 const int mod=1e9+7; 6 const int maxn=3e4+10; 7 double dp[maxn]; 8 int vis[maxn]; 9 vector<int>cnt; 10 vector<int>E[maxn]; 11 double ln[maxn]; 12 13 14 int main() 15 { 16 ios::sync_with_stdio(0); 17 cin.tie(0); 18 for(int i=2;i<maxn;i++) 19 { 20 if(vis[i]) 21 continue; 22 cnt.pb(i); 23 for(int j=i;j<maxn;j+=i) 24 { 25 vis[j]=1; 26 } 27 } 28 for(int i=2;i<maxn;i++) 29 ln[i]=log(i); 30 int tot=0; 31 for(auto &v:cnt) 32 { 33 ll temp=v; 34 tot++; 35 for(int j=1;j<=20;j++) 36 { 37 E[tot].pb(temp); 38 temp*=v; 39 if(temp>1e5) 40 break; 41 } 42 } 43 //cout<<cnt.size()<<'\n'; 44 for(int i=1;i<=tot;i++) 45 { 46 for(int j=maxn-1;j>=1;j--) 47 { 48 for(auto &v:E[i]) 49 { 50 if(j>=v) 51 dp[j]=max(dp[j],dp[j-v]+ln[v]); 52 } 53 } 54 } 55 int t; 56 cin>>t; 57 while(t--) 58 { 59 int b; 60 cin>>b; 61 cout<<fixed<<setprecision(9)<<dp[b]<<'\n'; 62 } 63 64 65 66 }

浙公网安备 33010602011771号