题解 CF1451A [Subtract or Divide]
思路
由题意得
对于任一个数\(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\times 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<<'\n';
continue;
}
if(n ==2)
{
cout<<1<<'\n';
continue;
}
if(n ==3)
{
cout<<2<<'\n';
continue;
}
if(n&1)
{
cout<<3<<'\n';
}
else
{
cout<<2<<'\n';
}
}
}