关于dp的复习

还有15days就noip心中都还没底.....

赶快再刷一些dp题

① LCIS

这个是LIS 与 LCS 的结合

dp[i][j] 表示的是A[i]之前与B[j]匹配并以B[j]结尾的LCIS

for(int k = 0; k < j; k++)

if(A[i] == B[j])

dp[i][j] = max(dp[i - 1][k], dp[i][j])

else dp[i][j] = dp[i - 1][j];

所以就可以有一个n三方的dp

#include<bits/stdc++.h>
#define R register 
#define IL inline
#define INF 0x3f3f3f3f
using namespace std;
const int max_n = 3010;

int n, m;
int a[max_n], b[max_n];
int dp[max_n][max_n];

int main()
{
	cin >> n;
	for(R int i = 1;i <= n; i++) scanf("%d", &a[i]);
	for(R int i = 1;i <= n; i++) scanf("%d", &b[i]);
	a[0] = b[0] = -INF;
	for(R int i = 1;i <= n; i++)
		for(R int j = 1;j <= n; j++)
			if(a[i] == b[j])
			{
				for(R int k = 0;k < j; k++)
				{
					if(a[i] > b[k]) 
					dp[i][j] = max(dp[i][j], dp[i - 1][k] + 1);
				}
			}else dp[i][j] = dp[i - 1][j];
	int ans = 0;
	for(R int i = 1;i <= n; i++)
		for(R int j = 1;j <= n; j++)
			ans = max(ans, dp[i][j]);
	cout << ans << endl;
	return 0;
}

但是可以优化 因为在i不变的时候 k -> 0-j 时候最大值只会与0-j 和 j + 1取并 

所以优化下来

#include<bits/stdc++.h>
#define R register 
#define IL inline
#define INF 0x3f3f3f3f
using namespace std;
const int max_n = 3010;

int n, m;
int a[max_n], b[max_n];
int dp[max_n][max_n];

int main()
{
	cin >> n;
	for(R int i = 1;i <= n; i++) scanf("%d", &a[i]);
	for(R int i = 1;i <= n; i++) scanf("%d", &b[i]);
	a[0] = b[0] = -INF;
	for(R int i = 1;i <= n; i++)
	{
		int val = 0;
		if(a[i] > b[0]) val = dp[i - 1][0];
		for(R int j = 1;j <= n; j++)
		{
			if(a[i] == b[j]) dp[i][j] = val + 1;
			else dp[i][j] = dp[i - 1][j];
//				for(R int k = 0;k < j; k++)
//				{
//					if(a[i] > b[k]) 
//					dp[i][j] = max(dp[i][j], dp[i - 1][k] + 1);
//				}
			if(a[i] > b[j]) val = max(val, dp[i - 1][j]);
		}
	} 
	int ans = 0;
	for(int i = 1;i <= n; i++)
	for(int j = 1;j <= n; j++)
	ans = max(dp[i][j], ans);
	cout << ans << endl;
	return 0;
}

  

posted @ 2018-10-26 09:11  aha浮云  阅读(142)  评论(0编辑  收藏  举报