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;
}