Codeforces 520B (bfs,dp,dfs,greedy)

本文介绍了解决从一个整数转换到另一个整数的最短步骤问题的四种算法实现方法,包括动态规划(DP)、深度优先搜索(DFS)、贪心算法及广度优先搜索(BFS)。通过对比不同算法的优缺点,帮助读者理解每种方法的适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

做法一,入门级dp,转移方程:

dp[i] = min(dp[i],dp[i/2]+1,dp[i+1]+1); //i为偶数
dp[i] = min(dp[i],dp[i+1]+1);//i为奇数

由于转移方程涉及两个方向,故选用类似于冒泡排序的while套for双重循环

#include <cstdio>
#include <algorithm>

using namespace std;

#define maxn 10050

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    int len = max(n,m*2);
    int dp[maxn*2];
    for(int i=0;i<len+1;i++) dp[i] = maxn;
    dp[n] = 0;

    bool flag = true;
    while(flag)
    {
        flag = false;
        for(int i=len-1;i>0;i--)
            if(dp[i] > dp[i+1] + 1)
            {
                flag = true;
                dp[i] = dp[i+1] +1;
            }
        for(int i=2;i<len+1;i+=2)
            if(dp[i] > dp[i/2]+1)
            {
                flag = true;
                dp[i] = dp[i/2]+1;
            }
    }
    printf("%d\n",dp[m]);
    return 0;
}


做法二,入门级dfs,需要加入数组来剪枝:

#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

#define maxn 10050

int ans[maxn*2];

void dfs(int loc,int key,int step)
{
    if(loc<=0) return ;
    if(step>ans[loc]) return ;
    ans[loc] = step;

    if(loc > key){dfs(key,key,step+loc-key);return ;}
    if(loc == key){ans[key] = min(ans[key],step);return ;}

    dfs(loc-1,key,step+1);
    dfs(loc*2,key,step+1);
}

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    memset(ans,0,sizeof(ans));
    for(int i=0;i<max(n,m*2)+1;i++) ans[i] = maxn;
    ans[n] = 0;

    dfs(n,m,0);
    printf("%d\n",ans[m]);
    return 0;
}

做法三,贪心,逆向思维,若m/2或(m+1)/2大于n时,先采用除2:

#include <cstdio>
#include <algorithm>

using namespace std;

#define maxn 10050

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    if(n>=m)
    {
        printf("%d\n",n-m);
        return 0;
    }
    int ans=0;
    while(m>0)
    {
        if(m&1)
        {
            ans++;
            m = m+1;
        }
        if(m/2 <= n)
        {
            printf("%d\n",ans+1+n-m/2);
            return 0;
        }else
        {
            ans++;
            m = m/2;
        }
    }
    return 0;
}


做法四,bfs

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值