[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;
    }
相关推荐
C++、Java和Python的菜鸟32 分钟前
第六章 统计初步
算法·机器学习·概率论
Cx330❀33 分钟前
【数据结构初阶】--排序(五):计数排序,排序算法复杂度对比和稳定性分析
c语言·数据结构·经验分享·笔记·算法·排序算法
散11243 分钟前
01数据结构-Prim算法
数据结构·算法·图论
起个昵称吧1 小时前
线程相关编程、线程间通信、互斥锁
linux·算法
阿巴~阿巴~1 小时前
深入解析C++ STL链表(List)模拟实现
开发语言·c++·链表·stl·list
myzzb2 小时前
基于uiautomation的自动化流程RPA开源开发演示
运维·python·学习·算法·自动化·rpa
旺小仔.2 小时前
双指针和codetop复习
数据结构·c++·算法
jingfeng5142 小时前
C++ STL-string类底层实现
前端·c++·算法
郝学胜-神的一滴3 小时前
基于C++的词法分析器:使用正则表达式的实现
开发语言·c++·程序人生·正则表达式·stl
雲墨款哥3 小时前
JS算法练习-Day10-判断单调数列
前端·javascript·算法