[Algorithm][综合训练][循环汉诺塔][kotori和素因子][dd爱科学]详细讲解

目录


1.循环汉诺塔

1.题目链接


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

  • 解法:动态规划

    • 重点 :找出重复子问题
    cpp 复制代码
    #include <iostream>
    using namespace std;
    
    const int MOD = 1e9 + 7;
    
    int main()
    {
        int n = 0;
        cin >> n;
        
        int x = 1, y = 2;
        for(int i = 2; i <= n; i++)
        {
            int prevX = x, prevY = y;
            x = (2 * prevY + 1) % MOD;
            y = ((2 * prevY) % MOD + 2 + prevX) % MOD;
        }
    
        cout << x << " " << y << endl;
    
        return 0;
    }

2.kotori和素因子

1.题目链接


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

  • 解法 :DFS枚举所有的情况

    cpp 复制代码
    #include <iostream>
    #include <cmath>
    #include <vector>
    using namespace std;
    
    int n = 0, path = 0, ret = 0x3f3f3f3f;
    vector<int> nums;
    vector<bool> use(1001, false); // 记录哪些值已经被使用过
    
    bool isPrim(int x)
    {
        if(x <= 1)
        {
            return false;
        }
        
        for(int i = 2; i <= sqrt(x); i++)
        {
            if(x % i == 0)
            {
                return false;
            }
        }
        
        return true;
    }
    
    void DFS(int pos)
    {
        if(pos == n)
        {
            ret = min(ret, path);
            return;
        }
    
        // 枚举 nums[pos] 的所有没有使⽤过的素因⼦
        for(int i = 2; i <= nums[pos]; i++)
        {
            if(nums[pos] % i == 0 && isPrim(i) && !use[i])
            {
                path += i;
                use[i] = true;
                DFS(pos + 1);
                path -= i;
                use[i] = false;
            }
        }
    }
    
    int main()
    {
        cin >> n;
        
        nums.resize(n, 0);
        for(auto& x : nums)
        {
            cin >> x;
        }
        
        DFS(0);
        
        if(ret == 0x3f3f3f3f)
        {
            cout << -1 << endl;
        }
        else
        {
            cout << ret << endl;
        }
        
        return 0;
    }

3.dd爱科学

1.题目链接


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

  • 模型抽象:就是最长非递减子序列模型

  • 解法:最长递增子序列 --> 贪心 + 二分

    • 贪心

      • 不关心前面的非递减子序列长什么样子,仅需知道长度为x的子序列末尾是多少即可
      • 存长度为x的所有子序列的末尾时,只用存最小的那个数即可
    • 二分优化 :因为随着长度,存入字符是递增的,所以在存入长度为x的所有子序列的末尾时,二分查找优化

    cpp 复制代码
    #include <iostream>
    #include <string>
    using namespace std;
    
    const int N = 1e6 + 10;
    
    int main()
    {
        int n = 0;
        string str;
        cin >> n >> str;
    
        char dp[N];
        int cur = 0;
        for(int i = 0; i < n; i++) // 遍历每个位置
        {
            char ch = str[i];
            
            // 找出ch应该放在记录数组的哪个位置
            if(cur == 0 || ch >= dp[cur])
            {
                dp[++cur] = ch;
            }
            else
            {
                // 二分找位置
                int left = 1, right = cur;
                while(left < right)
                {
                    int mid = (left + right) / 2;
                    if(dp[mid] > ch)
                    {
                        right = mid; 
                    }
                    else
                    {
                        left = mid + 1;
                    }
                }
                
                dp[left] = ch;
            }
        }
        
        cout << n - cur << endl;
        
        return 0;
    }
相关推荐
axxy20004 分钟前
leetcode之hot100---240搜索二维矩阵II(C++)
数据结构·算法
黑客Ash16 分钟前
安全算法基础(一)
算法·安全
yuanbenshidiaos32 分钟前
c++---------数据类型
java·jvm·c++
十年一梦实验室1 小时前
【C++】sophus : sim_details.hpp 实现了矩阵函数 W、其导数,以及其逆 (十七)
开发语言·c++·线性代数·矩阵
AI莫大猫1 小时前
(6)YOLOv4算法基本原理以及和YOLOv3 的差异
算法·yolo
taoyong0011 小时前
代码随想录算法训练营第十一天-239.滑动窗口最大值
c++·算法
这是我581 小时前
C++打小怪游戏
c++·其他·游戏·visual studio·小怪·大型·怪物
Uu_05kkq1 小时前
【C语言1】C语言常见概念(总结复习篇)——库函数、ASCII码、转义字符
c语言·数据结构·算法
fpcc1 小时前
跟我学c++中级篇——C++中的缓存利用
c++·缓存
呆萌很2 小时前
C++ 集合 list 使用
c++