最大互质子序列(动态规划)

互质的定义与代码实现

1. 互质的定义

互质(Coprime/Relatively Prime)是指两个或多个整数的最大公约数(GCD)为1。换句话说,如果两个数除了1以外没有其他公约数,则它们互质

。例如:

  • 8和9​:公约数只有1 → 互质
  • 6和12​:公约数有1、2、3、6 → 不互质
2. 判断互质的代码实现

以下是使用辗转相除法(欧几里得算法)​判断两个数是否互质的代码示例(Python和C++):

Python实现
import math

def is_coprime(a, b):
    return math.gcd(a, b) == 1

# 示例
print(is_coprime(8, 9))  # 输出: True
print(is_coprime(6, 12)) # 输出: False
C++实现
#include <iostream>
#include <algorithm>
using namespace std;

bool isCoprime(int a, int b) {
    return __gcd(a, b) == 1; // C++标准库中的gcd函数
}

int main() {
    cout << isCoprime(8, 9) << endl;  // 输出: 1 (True)
    cout << isCoprime(6, 12) << endl; // 输出: 0 (False)
    return 0;
}
3. 关键点说明
  • 辗转相除法原理​:通过反复取余计算最大公约数,若最终结果为1,则两数互质。
  • 特殊情况​:
    • 1和任何数互质​(因为1的公约数只有自身)。
    • 两个质数一定互质​(如7和11)。
4. 应用场景
  • 分数化简​:分子分母互质时,分数为最简形式。
  • 密码学​:RSA算法依赖大质数的互质性生成密钥。
5. 扩展:生成互质数列表

以下代码生成所有与n互质的数(小于等于n):

def list_coprimes(n):
    return [x for x in range(1, n+1) if math.gcd(x, n) == 1]

print(list_coprimes(9))  # 输出: [1, 2, 4, 5, 7, 8]
总结

互质的核心是最大公约数为1,代码实现依赖高效的GCD算法(如欧几里得算法)。实际应用中需注意边界条件(如1和质数)

题目:

代码实现

# include<iostream>
# include<vector>
# include<algorithm>
# include<math.h>
using namespace std;


int longestCoprimeSubsequence(vector<int>&nums)
{
	int n=nums.size();
	if(n==0)
	{
		return 0;
	}
	
	vector<int> dp(n,1); // dp[i]表示以nums[i]结尾的最长子序列长度
	
	for(int i=1;i<n;i++)
	{
		for(int j=0;j<i;j++)
		{
			if(__gcd(nums[i],nums[j])==1)
			{
				dp[i] = max(dp[i],dp[j]+1);
			}
		}
	}
	
	return *max_element(dp.begin(),dp.end());
}

int main()
{
	int n;
	cin>>n;
	
	vector<int> nums(n);
	for(int i=0;i<n;++i)
	{
		cin>>nums[i];
	}
	
	cout<<longestCoprimeSubsequence(nums)<<endl;
	return 0;
}

判断互质:

// 计算最大公约数
int gcd(int a, int b) {
    return b == 0 ? a : gcd(b, a % b);
}

如果最大公约数==1

则为互质

所以代码还可以这样写:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// 计算最大公约数
int gcd(int a, int b) {
    return b == 0 ? a : gcd(b, a % b);
}

int longestCoprimeSubsequence(vector<int>& nums) {
    int n = nums.size();
    if (n == 0) return 0;
    
    vector<int> dp(n, 1); // dp[i]表示以nums[i]结尾的最长子序列长度
    
    for (int i = 1; i < n; ++i) {
        for (int j = 0; j < i; ++j) {
            if (gcd(nums[i], nums[j]) == 1) { // 相邻元素互质
                dp[i] = max(dp[i], dp[j] + 1);
            }
        }
    }
    
    return *max_element(dp.begin(), dp.end());
}

int main() {
    int n;
    cin >> n;
    
    vector<int> nums(n);
    for (int i = 0; i < n; ++i) {
        cin >> nums[i];
    }
    
    cout << longestCoprimeSubsequence(nums) << endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值