21南京 J. Xingqiu's Joke 題解(思維+dp)
阿新 • • 發佈:2022-01-19
題目連結
題目思路
比賽的時候差不多想到了
其實就是他們的差值要麼不變,要麼除以因子,能除肯定要儘可能除
而有很多多餘的狀態沒有必要表示,只要記錄哪些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; }