#include <climits>
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

vector<int> GetDiv(int n)//求约数组合
{
    vector<int> t;
    for(int i = 2;i*i<=n;i++)
    {
        if(n%i==0)
        {
            t.push_back(i);
            if(i*i!=n)
            {
                t.push_back(n/i);
            }
        }
    }
    return t;
}


int main() {
    int n,m;
    cin>>n>>m;
    vector<int> dp(m-n+1,m+1);//设置一个不可能的最大次数

    dp[0] = 0;
    for(int i = n;i<m;i++)
    {
        int sub = i-n;
        if(dp[sub]<m+1)//跳到的才去检查
        {
            vector<int> div = GetDiv(i);
            for(auto num:div)
            {
                if(sub + num<=m-n)//防止越界
                {
                    dp[sub+num] = (dp[sub]+1)<dp[sub+num]?(dp[sub]+1):dp[sub+num];
                }
            }
        }
    }
    if(dp[m-n]==m+1)
    {
        cout<<-1;
    }
    else {
        cout<<dp[m-n];
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

花了好久时间,发现自己对动态规划的理解可以说不到位吧。

初始化动态规划,这个题里面如果初始化合理,省去一次判断,省下时间不说,也少了麻烦。

然后就是为了访问,动态规划不是非得要去整个连续的。

关于动态规划就是这点心得,动态规划本质就是递推,因此初始化正确的默认值,是很重要的。

2.求约数直接一次双取,之前没有如此导致时间复杂度过高。