nyoj 17 http://acm.nyist.net/JudgeOnline/problem.php?pid=17&rec=rec
动态规划的思想
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int dp[10000+10];
char a[10000+10];
int t;
int res;
int solve(char *a,int n){ // 参考挑战程序设计入门经典;
res = 0;
for(int i = 0; i < n; ++i){
dp[i] = 1;
for(int j = 0; j < i; ++j){
if(a[j] < a[i]){
dp[i] = max(dp[i], dp[j]+1);
}
}
res = max(res,dp[i]);
}
return res;
}
int main()
{
int len;
scanf("%d",&t);
for(int i = 0; i < t ;i++)
{
scanf("%s",a);
memset(dp,0,sizeof(dp));
len = strlen(a);
solve(a,len);
printf("%d\n", solve(a,len));
}
return 0;
}
状态转移dp[i] = max{ 1.dp[j] + 1 }; j<i;a[j]<a[i];
d[i]是以i结尾的最长上升子序列
与i之前的 每个a[j]<a[i]的 j的位置的 最长上升子序列+1后 的值比较
int solve(char *a,int n){ // 参考挑战程序设计入门经典;
res = 0;
for(int i = 0; i < n; ++i){
dp[i] = 1;
for(int j = 0; j < i; ++j){
if(a[j] < a[i]){
dp[i] = max(dp[i], dp[j]+1);
}
}
res = max(res,dp[i]);
}
return res;
}
优化方法
//dp[i]表示长度为i+1的上升子序列的最末尾元素;
//找到第一个比dp末尾大的,代替
void solve() {
fill(dp, dp + n, INF);
for (int i = 0; i < n; i++) {
*lower_bound(dp, dp + n, a[i]) = a[i];//返回一个指针
}
printf("%d\n", *lower_bound(dp, dp + n, INF) - dp;
}
//函数lower_bound()返回一个 iterator 它指向在[first,last)标记的有序序列中可以插入value,而不会破坏容器顺序的第一个位置,而这个位置标记了一个不小于value 的值。
本文介绍了一种求解最长上升子序列(LIS)问题的动态规划算法实现,并提供了详细的代码解释。通过状态转移方程dp[i]=max{1, dp[j]+1}

5915

被折叠的 条评论
为什么被折叠?



