题解 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';
			
		}
		
	}
 
 }
posted @ 2020-11-26 16:46  ·Iris  阅读(113)  评论(0编辑  收藏  举报