关于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; }
AC=Answer Coarse=粗劣的答案 WA=Wonderful Answer=好答案 TLE=Time Limit Enough=时间充裕 MLE=Memory Limit Enough=内存充裕 CE=Compile Easily=轻松通过编译 RE=Run Excel