[Algorithm][综合训练][过桥][最大差值][兑换零钱]详细讲解

目录

  • 1.过桥
    • 1.题目链接
    • 2.算法原理详解 && 代码实现
  • 2.最大差值
    • 1.题目链接
    • 2.算法原理详解 && 代码实现
  • 3.兑换零钱
    • 1.题目链接
    • 2.算法原理详解 && 代码实现


1.过桥

1.题目链接

  • 过桥

2.算法原理详解 && 代码实现

  • 解法:贪心 + BFS
    [Algorithm][综合训练][过桥][最大差值][兑换零钱]详细讲解_第1张图片

    #include 
    #include 
    using namespace std;
    
    int n = 0;
    vector<int> nums;
    
    int BFS()
    {
        int ret = 0;
        int left = 1, right = 1;
        while(left <= right)
        {
            ret++;
            
            int r = right;
            for(int i = left; i <= right; i++)
            {
                r = max(r, nums[i] + i);
                if(r >= n)
                {
                    return ret;
                }
            }
            
            left = right + 1;
            right = r;
        }
        
        return -1;
    }
    
    int main()
    {
        cin >> n;
        
        nums.resize(n + 1, 0);
        for(int i = 1; i <= n; i++)
        {
            cin >> nums[i];
        }
        
        cout << BFS() << endl;
    
        return 0;
    }
    

2.最大差值

1.题目链接

  • 最大差值

2.算法原理详解 && 代码实现

  • 解法:贪心 + 模拟
    • 遍历数组的过程中,使⽤⼀个变量标记⼀下当前位置之前所有元素的最⼩值即可
    int getDis(vector<int>& nums, int n) 
    {
        int ret = 0, minPrev = nums[0];
        for(int i = 1; i < n; i++)
        {
            minPrev = min(nums[i], minPrev);
            ret = max(ret, nums[i] - minPrev);
        }
    
        return ret;
    }
    

3.兑换零钱

1.题目链接

  • 兑换零钱

2.算法原理详解 && 代码实现

  • 单纯积累:完全背包问题
  • 解法:使用空间优化版本
    • 状态表示dp[i][j]:从前i个纸币中挑选,总和正好为j,此时所用的最少纸币的张数

    • 状态转移方程
      [Algorithm][综合训练][过桥][最大差值][兑换零钱]详细讲解_第2张图片

    • 初始化
      [Algorithm][综合训练][过桥][最大差值][兑换零钱]详细讲解_第3张图片

    • 返回值dp[n][aim]

    #include 
    #include 
    using namespace std;
    
    int main()
    {
        int n = 0, aim = 0;
        cin >> n >> aim;
    
        vector<int> arr(n + 1, 0);
        for(int i = 1; i <= n; i++)
        {
            cin >> arr[i];
        }
    
        vector<int> dp(aim + 1, 0x3f3f3f3f);
        dp[0] = 0;
    
        for(int i = 1; i <= n; i++)
        {
            for(int j = arr[i]; j <= aim; j++)
            {
                dp[j] = min(dp[j], dp[j - arr[i]] + 1);
            }
        }
    
        if(dp[aim] >= 0x3f3f3f3f)
        {
            cout << -1 << endl;
        }
        else
        {
            cout << dp[aim] << endl;
        }
    
        return 0;
    }
    

你可能感兴趣的:([OJ],#,[综合训练],Algorithm,综合训练,算法,C++,过桥,最大差值,兑换零钱)