思路
由题意得
对于任一个数(i)我们要求出他的最小的步数
设其为(num[i])
(num[i])必定可以被从(num[i-1])递推来
打一个表可以发现
当(i≥4)时,如果(i)是偶数那么(num[i] = 2)
若为奇数(num[i]=3)
证明
在$i equiv 0 pmod{2} $,
那么(2|i),
也就是说
(exists k , 2 imes k = i)
那么(num[i] = num[frac{i}{k} ]+1 = num[2]+1)
又因为(num[2])是除去(num[1])以外最小的
故当$i equiv 0 pmod{2} $证明成立
那么$i equiv 1 pmod{2} $时
(num[i] = num[i-1]+1)
因为$i-1 equiv 0 pmod{2} $
所以(num[i-1])可以被计算出
且(num[i-1])是除去(num[1],num[2])之外最小的
所以(num[i-1])也必定最小
证毕
Code
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define int long long
#define INF 1<<30
template<typename _T>
inline void read(_T &x)
{
x=0;char s=getchar();int f=1;
while(s<'0'||s>'9') {f=1;if(s=='-')f=-1;s=getchar();}
while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+s-'0';s=getchar();}
x*=f;
}
int num[2333];
signed main()
{
int T,n;
read(T);
while(T--)
{
read(n);
if(n == 1)
{
cout<<0<<'
';
continue;
}
if(n ==2)
{
cout<<1<<'
';
continue;
}
if(n ==3)
{
cout<<2<<'
';
continue;
}
if(n&1)
{
cout<<3<<'
';
}
else
{
cout<<2<<'
';
}
}
}