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