满分做法:
本题直接搜索即可,因为要记录最优值,直接spfa就好了。
#include<bits/stdc++.h>
using namespace std;
const int maxm=1e6+7;
int n,m;
int dis[maxm];
bool vis[maxm];
queue<int > q;
void spfa()
{
if(m<=n)
{
dis[m]=0;
vis[m]=1;
q.push(m);
}
else
{
dis[0]=3;
dis[n]=m-n;//直接删除
vis[0]=1;
q.push(0);
}
while(q.size())
{
int x=q.front();
q.pop();
vis[x]=0;
if(x<n&&dis[x+1]>dis[x]+1)
{
dis[x+1]=dis[x]+1;
if(!vis[x+1])
{
vis[x+1]=1;
q.push(x+1);
}
}
if(x>0&&dis[x-1]>dis[x]+1)
{
dis[x-1]=dis[x]+1;
if(!vis[x-1])
{
vis[x-1]=1;
q.push(x-1);
}
}
if(x>0)//有字符才复制
{
for(int i=2;x*(i-1)<=n;i++)
{
if(x*i>n&&dis[n]>dis[x]+2*(i+1)+x*i-n)//2*(i+1)为全选,复制,粘贴i-1次的总时间
{
dis[n]=dis[x]+2*(i+1)+x*i-n;
if(!vis[n])
{
vis[n]=1;
q.push(n);
}
}
if(x*i<=n&&dis[x*i]>dis[x]+2*(i+1))
{
dis[x*i]=dis[x]+2*(i+1);
if(!vis[x*i])
{
vis[x*i]=1;
q.push(x*i);
}
}
}
}
}
}
int main()
{
scanf("%d%d",&m,&n);
memset(dis,63,sizeof(dis));
spfa();
printf("%d
",dis[n]);
return 0;
}