[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;
    }
相关推荐
threerocks8 分钟前
Jev 入门第一课
算法
汉克老师1 小时前
GESP2026年9月认证C++三级( 第三部分编程题(2、分割字符串))精讲
c++·gesp·小学生·学c++编程
估值探索者1 小时前
【Python量化系统工程化 #08】关了 SSH 就停?systemd 让脚本开机自启 + 异常自动拉起
java·c++·人工智能·分类·数据挖掘
西柚研究生1234561 小时前
论文分析17:YOLOv11_UAVNet:无人机航拍图像专用目标检测算法
人工智能·python·深度学习·算法·目标检测
天若有情6731 小时前
C++花式魔改!手写头文件复刻Java语法,彻底打破编码思维定式
java·c++·语言做语言·jac++
qq_199886872 小时前
第7板块·第3节:CUTLASS 的 GEMM 实现与优化策略
c++·人工智能·gpu算力·cuda
hetao17338372 小时前
2026-09-17 hetao1733837 的刷题记录
c++·算法
午彦琳3 小时前
2026.9.17
数据结构·算法·leetcode
shada3 小时前
Boost.Process v2 在旧内核上报 `assign: Bad file descriptor`
c++
木井巳3 小时前
【记忆化搜索】不同路径
java·算法·leetcode·深度优先·剪枝·推荐算法