DP系列之(最长上升子序列 )

同样是一篇dp总结:

 

最长上升子序列

例题:https://vjudge.net/contest/278813#problem/C

普通写法的板子:(注意要从大往小找!!!)(待思索……)

#include 
#define ll long long
#define N 1005
//最长上升子序列,从大往小找的方法 
using namespace std;
const int modd=1e9+7;
ll inf=0x3f3f3f3f;
ll dp[N];
ll an[N];
ll h,maxx=0;
int main()
{
	int n;
	while(cin>>n)
	{
		maxx=-1;
		memset(dp,0,sizeof(dp));
		
		for(int i=1;i<=n;++i) 
		{
			cin>>an[i];
		}
		for(int i=n;i>=1;--i)
		{
			for(int j=1;jan[j]&&dp[i]+1>dp[j])
					dp[j]=dp[i]+1;
			}
		}
		for(int i=1;i<=n;++i)
			maxx=max(maxx,dp[i]+1); 
		cout<

优化写法(利用二分函数lower_bound),板子如下:

 

#include 
#define ll long long
#define N 1005
//最长上升子序列,从大往小找的方法,快速二分法 
using namespace std;
const int modd=1e9+7;
ll inf=0x3f3f3f3f;
ll dp[N];
ll an[N];
ll h,maxx=0;
int main()
{
	int n;
	while(cin>>n)
	{
		maxx=-1;
		memset(dp,0,sizeof(dp));
		
		for(int i=1;i<=n;++i) 
		{
			cin>>an[i];
		}
		int len=1;
		//拿dp[i]来当模拟栈 
		dp[1]=an[1];
		for(int i=2;i<=n;++i)//注意是从 
		{
			if(an[i]>dp[len])
			{
				dp[++len]=an[i];
			}
			else
			{
				int site=std::lower_bound(dp+1,dp+len+1,an[i])-dp;
				dp[site]=an[i];
			}
		}
		//lower_bound的右区间是开区间,如果找到了会返回地址,否则返回比这个值大一点的值的地址 
		cout<

 

最长公共子串

 待更……

你可能感兴趣的:(动态规划,dp,最长公共子串,最长上升子序列)