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;
    }
    
    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM