动态规划-序列问题

<1>最长公共子序列

//最长公共子序列
#include
using namespace std;
const int N = 1e3;//s1 s2的最大长度 
string s1,s2;
int dp[N][N]; //表示s1的前i个字符和s2的前j个字符的最长公共子序列长度 

//常规方法 ,空间复杂度为o(s1.size()*s2.size()) 
int main(){
	cin>>s1;
	cin>>s2;
	for(int i = 0;i <= s1.size();i++){
		dp[i][0] = 0;
	}
	for(int i = 0;i <= s2.size();i++){
		dp[0][i] = 0;
	}
	for(int i = 1;i <= s1.size();i++){
		for(int j = 1;j <= s2.size();j++){
			if(s1[i-1] == s2[j-1]){
				dp[i][j] = dp[i-1][j-1] + 1;
			}
			else{
				dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
			}
		}
	}
	cout<

<2>最长递增子序列

//最长递增子序列
#include
using namespace std;
const int N = 1e5;
int nums[N];
int dp[N];//dp表示以第i个元素结尾的最长递增序列


int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	memset(dp,1,sizeof dp);
	int n;cin>>n;//输入nums的长度
	int len = 1;
	for(int i = 1;i <= n;i++)
		cin>>nums[i]; 
	for(int i = 1;i < n;i++){
		for(int j = 0;j < i;j++){
			if(nums[i] > nums[j]){
				dp[i] = max(dp[i],dp[j] + 1);
			}
		} 
		len = max(len,dp[i]);
	}
	cout<

优化

//最长递增序列(优化) 
#include 
using namespace std;

int lengthOfLIS_Greedy(vector& nums) {
    vector tail;
    for (int num : nums) {
        auto it = lower_bound(tail.begin(), tail.end(), num);
        if (it == tail.end()) {
            tail.push_back(num);
        } else {
            *it = num;
        }
    }
    return tail.size();
}

int main() {
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); 
    int n;
    cin >> n;
    vector nums(n);
    for (int i=0; i> nums[i];
    }
    cout << lengthOfLIS_Greedy(nums) << endl;
    return 0;
}
 

<3>编辑距离

//编辑距离
#include 
using namespace std;

const int N = 1000; // 避免数组越界
int dp[N][N];

int main() {
    string s1, s2;
    cin >> s1 >> s2;
    int len1 = s1.size(), len2 = s2.size();

    // 初始化
    for (int i = 0; i <= len1; i++) dp[i][0] = i;
    for (int j = 0; j <= len2; j++) dp[0][j] = j;

    // 动态规划填表
    for (int i = 1; i <= len1; i++) {
        for (int j = 1; j <= len2; j++) {
        	/*
        	替换操作成本为2 
        	删除,插入操作成本为1
			*/ 
            int cost = (s1[i-1] == s2[j-1]) ? 0 : 2;
            dp[i][j] = min({
                dp[i-1][j] + 1,    // 删除 s1[i-1]
                dp[i][j-1] + 1,    // 插入 s2[j-1]
                dp[i-1][j-1] + cost // 替换或直接匹配
            });//因为min函数最多只能接受两个参数,所以要嵌套 
        }
    }

    cout << dp[len1][len2] << endl;
    return 0;
}

你可能感兴趣的:(动态规划,算法,c++,蓝桥杯,c语言)