AtCoder Regular Contest 124 C - LCM of GCDs (记忆化搜索)
-
题意:有两个容器\(x\)和\(y\),\(n\)对数\(a[i]\)和\(b[i]\),每次选一对数将\(a[i]\)或者\(b[i]\)放入容器\(x\)或\(y\)中,全部放完后将\(x\)和\(y\)中所有数求gcd,然后得到的两个数求lcm,问能得到的最大lcm是多少.
-
题解:这题的\(n\)给的很小,但是直接dfs肯定是不行的,因为每次都是求gcd,所以可考虑每层搜索的时候记忆化一下,如果搜到某一层的时候容器内的两个数已经出现过了,那么直接return即可.
-
代码:
#include <bits/stdc++.h> #define ll long long #define fi first #define se second #define pb push_back #define me memset #define rep(a,b,c) for(int a=b;a<=c;++a) #define per(a,b,c) for(int a=b;a>=c;--a) const int N = 1e6 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;} ll lcm(ll a,ll b) {return a/gcd(a,b)*b;} int n; ll a[N],b[N]; vector<map<PLL,ll>> dp(N); ll dfs(int u,ll xa,ll xb){ if(dp[u-1][make_pair(xa,xb)]) return dp[u-1][make_pair(xa,xb)]; if(u==n+1) return dp[u-1][make_pair(xa,xb)]=lcm(1ll*xa,1ll*xb); ll res1=dfs(u+1,gcd(xa,a[u]),gcd(xb,b[u])); ll res2=dfs(u+1,gcd(xa,b[u]),gcd(xb,a[u])); return dp[u-1][make_pair(xa,xb)]=max(res1,res2); } int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); cin>>n; rep(i,1,n) cin>>a[i]>>b[i]; cout<<dfs(2,a[1],b[1])<<'\n'; return 0; }
𝓐𝓬𝓱𝓲𝓮𝓿𝓮𝓶𝓮𝓷𝓽 𝓹𝓻𝓸𝓿𝓲𝓭𝓮𝓼 𝓽𝓱𝓮 𝓸𝓷𝓵𝔂 𝓻𝓮𝓪𝓵
𝓹𝓵𝓮𝓪𝓼𝓾𝓻𝓮 𝓲𝓷 𝓵𝓲𝓯𝓮