[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;
    }
相关推荐
悠仁さん3 分钟前
【C++】set map 使用
java·前端·c++
艾莉丝努力练剑15 分钟前
【AI大模型接入SDK】ChatServer问题修复
c++·学习·ai·大模型·sdk
扶尔魔ocy1 小时前
【QT C++】常用设计模式
c++·设计模式
晚风予卿云月1 小时前
【C++高并发内存池】 2.ThreadCache设计
开发语言·c++·高并发内存池·tcmalloc
郝学胜-神的一滴2 小时前
游戏设计:原型与开发 19:U3D工位布置与性格说明书
人工智能·算法·unity·unreal engine·游戏策划·游戏设计
東隅已逝,桑榆非晚2 小时前
红黑树:从概念到实现
数据结构·c++·笔记·学习
艾莉丝努力练剑2 小时前
【AI大模型接入SDK】ChatServer接口测试
网络·c++·人工智能·学习·ai·大模型·sdk
D e re k ZH2 小时前
C++ 模板与泛型编程进阶(No 2)
开发语言·c++
hahaha60163 小时前
数字图像时域滤波或者3D降噪算法FPGA实现
算法·计算机视觉·fpga开发
YSL0701243 小时前
一文通关-----树和二叉树
数据结构·算法