• bzoj4275 [ONTAK2015]Badania naukowe


    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4275

    【题解】

    考虑预处理出来a[1..i]和b[1..j]的LCS,记为$f_{i,j}$;a[i..n]和b[j..m]的LCS,记为$g_{i,j}$。

    同时预处理出来如果从a[i]开始匹配c串,终止位置,记为$af_i$;同理记录$bf_i$。

    那么枚举c串在A,B中开始的位置$i$和$j$,就有贡献为$f_{i-1,j-1} + |c| + g_{af_i+1, bf_i+1}$

    直接做即可,复杂度$O(nm)$。

    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int N = 3e3 + 10;
    const int mod = 1e9+7;
    
    int n, m, K;
    int a[N], b[N], c[N];
    
    int f[N][N], g[N][N], af[N], bf[N];
    
    int main() {
        cin >> n; for (int i=1; i<=n; ++i) scanf("%d", a+i);
        cin >> m; for (int i=1; i<=m; ++i) scanf("%d", b+i);
        cin >> K; for (int i=1; i<=K; ++i) scanf("%d", c+i);
        for (int i=1; i<=n; ++i)
            for (int j=1; j<=m; ++j) {
                f[i][j] = max(f[i-1][j], f[i][j-1]);
                if(a[i] == b[j]) f[i][j] = max(f[i][j], f[i-1][j-1] + 1);
            }
        for (int i=n; i; --i)
            for (int j=m; j; --j) {
                g[i][j] = max(g[i+1][j], g[i][j+1]);
                if(a[i] == b[j]) g[i][j] = max(g[i][j], g[i+1][j+1] + 1);
            }
        if(!K) {
            cout << f[n][m] << endl;
            return 0;
        }
        for (int i=1; i<=n; ++i) {
            int k = 0;
            af[i] = n+1;
            for (int j=i; j<=n; ++j) {
                if(a[j] == c[k+1]) ++k;
                if(k == K) {
                    af[i] = j;
                    break;
                }
            }
        }
        for (int i=1; i<=m; ++i) {
            int k = 0;
            bf[i] = m+1;
            for (int j=i; j<=m; ++j) {
                if(b[j] == c[k+1]) ++k;
                if(k == K) {
                    bf[i] = j;
                    break;
                }
            }    
        }
    //    for (int i=1; i<=n; ++i) cout << af[i] << ' '; cout << endl;
    //    for (int i=1; i<=m; ++i) cout << bf[i] << ' '; cout << endl;
        int ans = -1;
        for (int i=1, ii, jj; i<=n; ++i)
            for (int j=1; j<=m; ++j) {
                ii = af[i], jj = bf[j];
                if(ii == n+1 || jj == m+1) continue;
                ans = max(ans, f[i-1][j-1] + g[ii+1][jj+1] + K);
            }
        cout << ans;
        return 0;
    }
    View Code
  • 相关阅读:
    Linux系统负载
    full nat
    close wait 状态的随想
    记录一下 性能分析问题
    golang 反射
    socket里面那个又爱又恨的锁
    Difference between skbuff frags and frag_list
    浅析TCP协议---转载
    http 怎样关闭
    http 响应 ngx_http_send_header ngx_http_output_filter
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj4275.html
Copyright © 2020-2023  润新知