[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;
    }
相关推荐
June`1 小时前
常量内存和只读缓存
c++·人工智能·算法·cuda
一条大祥脚1 小时前
ABC468 扫描线|贡献法|二阶差分|线段树优化DP
数据结构·算法
happyprince1 小时前
篇2-bitsandbytes-具体观-算法与实现剖析
算法
Cx330❀1 小时前
【Linux网络】深入 HTTP 协议(五):从 Cookie/Session 原理到 C++ 源码实战
linux·运维·服务器·开发语言·网络·c++·http
鸿芯微控科技1 小时前
MFC气体转换系数怎么用?标定气体、换算方向与Python批量计算
c++·python·mfc
hPw0eKIqD10 小时前
C++ 模板参数推导问题小记(非推导上下文)
开发语言·c++
程序员爱德华10 小时前
Python与C++:异同点对比
c++·python
普通攻击往后拉11 小时前
Leetcode 206. 反转链表
算法·leetcode·链表
@syh.12 小时前
【贪心】矩阵消除游戏
算法·游戏·矩阵
可编程芯片开发12 小时前
基于零极点配置的PID控制系统simulink建模与仿真
算法