【动态规划】关于子序列的例题

1.最大子序列和

#include<iostream>
using namespace std;
int main()
{
	int n;
	int ans = -1000000;
	int sum = 0;
	scanf("%d", &n);
	int *a = new int[n + 5];
	for(int i = 0; i < n; i++){
		scanf("%d", &a[i]);
		ans = max(ans, a[i]);
	}
	if(ans <= 0){
		cout << ans;
	}
	else{
		for(int i = 0; i < n; i++){
			sum += a[i];
			if(sum < 0){
				sum = 0;
			}
			else if(sum >= 0){
				ans = max(sum, ans);
			}
		} 
		cout << ans;
	}
	delete []a;
	return 0;
}

输入:
6
-3 11 -4 13 -2 -8
输出:
20(即11 -4 13构成最大子序列和)

2.最长递增子序列长度

#include<iostream>
using namespace std;
int main()
{
	int n;
	int *a = new int[n + 5];
	int *len = new int[n + 5]; 
	scanf("%d", &n);
	for(int i = 0; i < n; i++){
		scanf("%d", &a[i]);
	}
	
	len[0] = 1;
	int ans = 1;
	for(int i = 1; i < n; i++){
		len[i] = 1;
		for(int j = i - 1; j >= 0; j--){
			if(a[j] < a[i]){
				len[i] = max(len[j] + 1, len[i]);
			}
		}
		ans = max(ans, len[i]);
	}
	cout << ans;
	delete []a;
	return 0;
}

输入:
6
3 2 6 1 4 5
输出:
3(即1 4 5或2 4 5或3 4 5)

3.最长公共子序列
(来自计蒜客老师的讲解,感觉是目前看到比较简洁容易理解的)

#include<iostream>
#include<cstring>
using namespace std;

int dp[105][105]; //表示字符串a,b分别搜到第i个和第j个 

int main()
{
	string a, b;
	cin >> a >> b;
	memset(dp, 0, sizeof(dp));
	int lena = a.length();
	int lenb = b.length();
	for(int i = 1; i <= lena; i++){
		for(int j = 1; j <= lenb; j++){
			if(a[i - 1] == b[j - 1]){
				dp[i][j] = dp[i - 1][j - 1] + 1;
				//如acd和acbd,a[2] = b[3],dp[3][4] = dp[2][3] + 1,即ac与acb比较的结果+1,必须a,b同增1位dp才可能+1 
			}
			else{
				dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
				//把acd和acbd,acde和acb比较的结果中更大的一个作为dp[i][j] 
			}
		}
	}
	cout << dp[lena][lenb];
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值