动态规划练习

 最长公共子序列

【输入形式】

两个给定字符串

【输出形式】

两个序列最大长度公共子序列的长度。

【样例输入】

abcfbc abfcab

【样例输出】

4
#include<iostream>
#include<string.h>
using namespace std;
int L[1001][1001];
int S[1001][1001];
int CommonOrder(char x[], int m, char y[], int n, char z[]) {
	int i, j, k;
	for (i = 0; i <= m; i++) {
		L[i][0] = 0;
	}
	for (j = 0; j<= n; j++) {
		L[0][j] = 0;
	}
	for (i = 1; i <= m; i++) {
		for (j = 1; j <= n; j++) {
			if (x[i-1] == y[j-1]) {
				L[i][j] = L[i - 1][j - 1] + 1; S[i][j] = 1;
			}
			else if(L[i][j-1]>=L[i-1][j]){
				L[i][j] = L[i][j - 1]; S[i][j] = 2;
			}
			else {
				L[i][j] = L[i-1][j]; S[i][j] = 3;
			}
		}
	}
	i = m; j = n;
	k = L[m][n]-1;
	while (i > 0 && j > 0) {
		if (S[i][j] == 1) {
			z[k] = x[i-1]; k--; i--; j--;
		}
		else if (S[i][j] == 2) {
			j--;
		}
		else {
			i--;
		}
	}
	for (k = 0; k < L[m][n]; k++) {
		cout << z[k];
	}
	return L[m][n];
}
int main() {
	char x[1000], y[1000],z[1000];
	cin >> x >> y;
	int x_len = strlen(x);
	int y_len = strlen(y);
	/*cout << x_len << y_len;*/
	cout<<CommonOrder(x, x_len, y, y_len, z)<<endl;
}

求长度为k的递增子序列个数 

 

#include<iostream>
using namespace std;

const int N = 1010, inf = 0x3f3f3f3f, mod = 1000007;
int n, m, res=0;
int a[N], dp[N][N];//dp[i][j]表示以a[i]结尾长度为j的子序列个数

int main() {
	cin >> n >> m;//n为序列长度,要计算长度为m的子序列个数
	for (int i = 1; i <= n; i++) cin >> a[i], dp[i][1] = 1;//初始化

	for (int i = 1; i <= n; i++) {//以a[i]结尾的子序列
		for (int j = 1; j <= m; j++) {//以a[i]结尾的长度为j(求到题目要求的长度m即可)子序列
			for (int k = 1; k < i; k++) {//遍历看a[i]前面的原始是否存在小于a[i]
				if (a[i] > a[k])
					dp[i][j] += dp[k][j - 1];
			}
		}
	}

	for (int i = 1; i <= n; i++) {
		res = (res + dp[i][m]) % mod;
	}
	cout << res << endl;
	return 0;
}


 求最长递增子序列长度

#include<iostream>
using namespace std;
//求最长递增子序列长度
int a[10010];
int L[10010];//长度数组:以a[i]结尾的最长递增子序列长度
void IncreaseOrder(int a[], int n) {
	int index,i,j;
	for ( i = 1; i <= n; i++) {
		L[i] = 1;
	}
	for (i = 1; i <= n; i++) {//填充L[i]数组
		int max = 1;
		for (j = i - 1; j > 0; j--) {
			if (a[j] < a[i] && max<L[j]+1) {
				max = L[j] + 1;
				L[i] = max;
			}
		}
	}
	//遍历L[i],找最大长度
	for (index = 1, i = 2; i <= n; i++) {
		if (L[index] < L[i]) {
			index = i;
		}
	}
	cout << "最长递增子序列长度: " << L[index] << endl;
	return;
}
int main() {
	int n;
	cin >> n ;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	IncreaseOrder(a, n);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值