請你設計一個程序幫助bx2k水羣吧。
#include<iostream>
#include<stdio.h>
#include<queue>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1e6+20;
int n,ans[maxn],a[]={2,3,5,7,11,13};
bool vis[maxn];
queue<int> q;
void spfa(){
q.push(1);vis[1]=1;
while(!q.empty()){
int cur=q.front();q.pop();vis[cur]=0;
for(int i=0;i<6;i++){
if(cur*a[i]<n+20&&ans[cur*a[i]]>ans[cur]+a[i]){
ans[cur*a[i]]=ans[cur]+a[i];
if(!vis[cur*a[i]]) q.push(cur*a[i]),vis[cur*a[i]]=1;
}
}
if(ans[cur-1]>ans[cur]+1){
ans[cur-1]=ans[cur]+1;
if(!vis[cur-1]) q.push(cur-1),vis[cur-1];
}
}
}
int main(){
scanf("%d",&n);
for(int i=2;i<=n+20;i++) ans[i]=inf,vis[i]=0;
spfa();
printf("%d\n",ans[n]);
}
記憶化搜索
#include<iostream>
#include<stdio.h>
#include<queue>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1e6+20;
int n,ans[maxn][2],a[]={2,3,5,7,11,13};
queue<int> q;
int s(int n,int way){
if(n==1) return 0;
if(ans[n][way]) return ans[n][way];
ans[n][way]=inf;
for(int i=0;i<6;i++)
if(n%a[i]==0) ans[n][way]=min(ans[n][way],s(n/a[i],1)+a[i]);
if(!way) return ans[n][way];
ans[n][0]=ans[n][1];
for(int i=1;i<5;i++)
ans[n][way]=min(ans[n][way],s(n+i,0)+i);
return ans[n][way];
}
int main(){
scanf("%d",&n);
printf("%d\n",s(n,1));
}