题目大意:给出一个数n,有3种操作,可以乘以2或乘以3或+1,问最少需要多少步能从1到n
1<=n<=1e18
思路:记忆化搜索,我们从n开始dfs,因为/2或/3肯定比-1好,所以我们就有两种选择,设当前数字为x,要么x/=3,然后操作数+=1+n%3,或者x/=2,然后操作数+=1+n%2,两种方法得到的最小值即为1到x所需的最小操作数,递归直到得到1到n的最小操作数
#include<bits/stdc++.h>
//#include<__msvc_all_public_headers.hpp>
using namespace std;
typedef long long ll;
ll ans = 1e18 + 1;
map<ll, ll>ma;
ll dfs(ll x)
{//求从1到x需要的最少操作数
if (x <= 0)
return 1e18;//不能有0以下的数
if (ma.find(x) != ma.end())
return ma[x];
if (x == 1)
{
return 0;
}
else
{
ll y1 = x / 3;
ll y2 = x / 2;
ma[x] = min(dfs(y1) + 1 + x % 3, dfs(y2) + 1 + x % 2);//分别求出除以2和除以3的数到x需要的最少操作数
return ma[x];
}
}
int main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(false);
int t;
cin >> t;
while (t--)
{
ma.clear();
ll n;
cin >> n;
ans = 1e18 + 1;
ll temp = dfs(n);
cout << temp << endl;
}
return 0;
}