这是我第一次模拟题测试点全部AC。。。
同机房的DALAO都用的BFS
然而我用的DP(其实不会BFS)
话不多说,上题!
(灰常详细)DP解法:
重点还是状态转移方程式的推导
1个点i要么是后面的位置i-1往前走一步,i+1往后走一步即dg[i]=
或者是一个点i*2从i瞬移一步。
如果是自身的话也可能不走。
此时就要找哪一种走的最少了
状态转移方程就是dg[i]=min(dg[i],min(dg[i-1]+1,dg[i+1]+1))
和dg[i*2]=min(dg[i*2],dg[i]+1)
推导出方程就比较容易解了
#include<cstring> #include<iostream> #include<cstdio> #include<algorithm> using namespace std; int dp[2000005];//数组开两倍是因为有可能走到K点后面再往前走。 int main() {freopen("meet.in","r",stdin);freopen("meet.out","w",stdout);int N,K;scanf("%d%d",&N,&K);memset(dp,0x7f,sizeof(dp));//将所有数初始化到最大值dp[N]=0;//从N开始,步数为0for(int i=N-1;i>=0;i--)//先往前推,把前面的步数通过dp[N]算出来;{dp[i]=min(dp[i],(dp[i-1]+1,dp[i+1]+1));dp[i*2]=min(dp[i*2],dp[i]+1);}for(int i=N;i<=K;i++)//再往后推,计算后面的步数。{dp[i]=min(dp[i],min(dp[i-1]+1,dp[i+1]+1));dp[i*2]=min(dp[i*2],dp[i]+1);}cout<<dp[K]; //打印K点的步数。return 0; }
看起来还是挺简单的
我再去研究一下广搜做法。。。