1. 程式人生 > 其它 >21南京 J. Xingqiu's Joke 題解(思維+dp)

21南京 J. Xingqiu's Joke 題解(思維+dp)

題目連結

題目思路

比賽的時候差不多想到了

其實就是他們的差值要麼不變,要麼除以因子,能除肯定要儘可能除

而有很多多餘的狀態沒有必要表示,只要記錄哪些dif改變的情況即可其實沒那麼難,就是要去掉很多表示狀態即

程式碼

#include<bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int maxn=2e5+5,inf=0x3f3f3f3f,mod=1e9+7;
const double eps=1e-6;
int n;
int a,b;
map<pii,int> dp;
vector<int> vec;
int dfs(int b,int dif){
    if(b==1) return 0;
    if(dp.count({b,dif})) return dp[{b,dif}];
    int ans=b-1;
    for(auto x:vec){
        if(dif%x==0){
            if(b>=x){
                ans=min(ans,dfs(b/x,dif/x)+b%x+1);
            }
            ans=min(ans,dfs(b/x+1,dif/x)+x-b%x+1);
        }
    }
    return dp[{b,dif}]=ans;
}
signed main(){
    int _;scanf("%d",&_);
    while(_--){
        vec.clear();
        dp.clear();
        scanf("%d%d",&a,&b);
        if(a<b) swap(a,b);
        int dif=a-b;
        for(int i=2;1ll*i*i<=dif;i++){
            if(dif%i==0){
                 while(dif%i==0){
                    dif/=i;
                }
                vec.push_back(i);
            }
        }
        if(dif!=1){
            vec.push_back(dif);
        }
        printf("%d\n",dfs(b,a-b));
    }
    return 0;
}

不擺爛了,寫題