Codeforces Round #295 (Div. 2) B. Two Buttons (DP)
阿新 • • 發佈:2020-10-22
-
題意:有兩個正整數\(n\)和\(m\),每次操作可以使\(n*=2\)或者\(n-=1\),問最少操作多少次使得\(n=m\).
-
題解:首先,若\(n\ge m\),直接輸出\(n-m\),若\(2*n>=m\),分\(m\)的奇偶判斷一下,如果是奇數就輸出\(n-(m+1)/2+2\),是偶數就輸出\(n-m/2+1\).否則我們就需要用dp來求解,因為是求最小值,所以先初始化將所有值設為\(INF\),\(dp[i]\)表示從\(n\)到\(m\)的操作次數最少的最優解,首先需要更新\([1,n]\)的狀態,這個不難寫,\(dp[i]=dp[i+1]+1\),然後我們就可以從\(1\)
-
程式碼:
int n,m; int dp[N]; int main() { //ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); n=read(),m=read(); if(n>=m){ printf("%d\n",n-m); return 0; } if(m<=2*n){ if(m&1){ int cnt=(m+1)/2; printf("%d\n",n-cnt+2); } else printf("%d\n",n-m/2+1); return 0; } me(dp,INF,sizeof(dp)); dp[n]=0; for(int i=n-1;i>=1;--i) dp[i]=dp[i+1]+1; for(int i=1;i<=m;++i){ dp[i]=min(dp[i],dp[i+1]+1); dp[i*2]=min(dp[i*2],dp[i]+1); } printf("%d\n",dp[m]); return 0; }