Jeanny
寂兮,寥兮,独立不改,周行而不殆

&最长上升子序列
3 4 1 5 2 7 6

dfs(int i, int j, int len)
表示前i的位置,以a[j]为结尾的最长上升子序列长度为len

dfs(i+1, a[j], len)
dfs(i+1, a[i+1], len+1)

dp[i][len] 前i个元素,组成长度为len的lis序列,对应的结尾数字的最小值

g[i]//表示最长上升长度为i时,最小的数值

例如:
1 8 6 10 7
g[1] = 1
g[2] = 8->6
g[3] = 10->7

for(int i = 1; i <= n; i++){
a[i] 和前面所有值比较
}

&树状数组求顺序对,-_-!

3 4 1 5 2 7 6

1 2 3 4 5 6 7
    0             从1-2没有被标记的
      1           从1-3找有几个数字标记了
0                 从1-0
        3         从1-4有三个标记了
  1               从1-1有一个标记了
            5     从1-6有5个标记了
          5       从1-5有5个标记了

加在一起,可以得到顺序对的个数

&树状数组求最长上升子序列

3 4 1 5 2 7 6

1 2 3 4 5 6 7
    1
      2
1
        3       从1-4找最大值    
  2       
            4
           4

&最长公共子序列

暴力:dfs(i,j,len)

dp[i][len] 表示第一串前i位置,构成lcs时,第二串的最小位置

#include <bits/stdc++.h>
using namespace std;
string sa, sb;
int loc[200][500005], res, num[200], dp[1005][1005], mx = 0x3f3f3f3f;
int find(char x, int n, int cp) {
    int l = 1, r = n, ans = mx;
    while (l <= r) {
        int mid = (l + r) >> 1;
        if (loc[x - 'a'][mid] > cp) {  //找最小的位置
            r = mid - 1;
            ans = mid;
        } else
            l = mid + 1;
    }
    if (ans == mx)
        return mx;
    else
        return loc[x - 'a'][ans];
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> sa >> sb;
    int la = sa.size(), lb = sb.size();
    for (int i = 0; i < lb; i++) {
        loc[sb[i] - 'a'][++num[sb[i] - 'a']] = i;
        // cout<<sb[i]<<" "<<num[sb[i]-'a']<<" "<<loc[sb[i]-'a'][num[sb[i]-'a']]<<endl;
    }
    memset(dp, 0x3f, sizeof dp);
    for (int i = 0; i < la; i++) dp[i][0] = -1;  //所有的len=1,都是可以找的

    for (int i = 0; i < la; i++) {
        for (int len = 1; len <= i + 1; len++) {  //公共子序列的长度
            int val;
            if (i == 0) {
                val = find(sa[i], num[sa[i] - 'a'], -1);
            }
            // else if(dp[i-1][len-1] == mx) pos = mx; //dp[4][3] = mx, error, dp[4][3] = min(dp[i][3])
            else {
                val = find(sa[i], num[sa[i] - 'a'], dp[i - 1][len - 1]);
            }
            // if(pos == mx)
            //     dp[i][len] = mx;
            // else
            dp[i][len] = (i != 0 ? min(dp[i - 1][len], val) : val);  //达到这个长度,最小的位置
            // cout<<"ttt: "<<sa[i]<<" "<<i<<" "<<len<<" "<<val<<" "<<dp[i][len]<<endl;
            res = max(res, dp[i][len] != mx ? len : 0);  //答案
        }
    }
    cout << res << endl;
    return 0;
}
/*

mrhnobtxjawybtyvz
ntcjumuvztkgbpgwscpawj

mrjujz
rcmjruzt

ntcjumuvztkgbpgwscpawjvfksvgzisarblzqcsg
mrhnobtxjawybtyvzfiiupiwgzbzyunrdvijmdgvciharilvcne

*/

posted on 2024-03-07 10:08  Jeanny  阅读(13)  评论(0)    收藏  举报