欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

xtu-1265 Longest Common Subsequence(字符串/计数)

程序员文章站 2024-03-15 15:20:18
...

Longest Common Subsequence

Accepted : 11   Submit : 105
Time Limit : 3000 MS   Memory Limit : 65536 KB

Longest Common Subsequence

Bobo has a sequence A=(a 1 ,a 2 ,,a n )  of length n . He would like to know f(0),f(1),f(2)  and f(3)  where f(k)  denotes the number of integer sequences X=(x 1 ,x 2 ,x 3 )  where:

  • 1x 1 ,x 2 ,x 3 m ;
  • The length of longest common subsequence of A  and X  is exactly k .

Note:

  • u  is a subsequence of v  if and only if u  can be obtained by removing some of the entries from v  (possibly none).
  • u  is common subsequence of v  and w  if and only if u  is subsequence of v  and w .

Input

The input contains zero or more test cases and is terminated by end-of-file. For each case,

The first line contains two integers n,m . The second line contains n  integers a 1 ,a 2 ,,a n  .

  • 1n200 
  • 1m,a 1 ,a 2 ,,a n 10 6  
  • The number of tests cases does not exceed 10 .

Output

For each case, output four integers which denote f(0),f(1),f(2),f(3) .

Sample Input

3 3
1 2 2
5 3
1 2 3 2 1

Sample Output

1 14 11 1
0 1 17 9

Note

For the second sample, X=(3,3,3)  is the only sequence that the length of longest common subsequence of A  and X  is 1 . Thus, f(1)=1 .


A中只要ai>m则舍去,因为X取不到ai。设A中一共有cnt种元素,那么还剩m-cnt个元素没有。

枚举x1,x2,x3的值∈[1,cnt+1],其中cnt+1表示x取A中不存在的值。
预处理出nxt[i][c],表示第i个元素后,元素c是出现在第几个位置。

枚举集合(x1,x2,x3)的子集,找出是A的子序列的最大子集,如果xi不在这个子集中且xi的取值为cnt+1,那么方案数*(m-cnt)

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MX = 1e6 + 5;
int vis[MX], a[205], sz, cnt;
int nxt[205][205], t[5], st[5];
LL f[5];
int solve(int len) {
    if(len == 0) return 1;
    int i = 0, index;
    for(index = nxt[0][st[i]]; index > 0 && i < len;) {
        index = nxt[index][st[++i]];
    }
    if(i==len) return 1;
    return 0;
}
int S, mx;
void dfs(int len, int i, int sta) {
    if(i > 2) {
        if(solve(len) && mx < len) {
            S = sta;
            mx = len;
        }
    } else {
        dfs(len, i + 1, sta);
        st[len] = t[i];
        dfs(len + 1, i + 1, sta | (1 << i));
    }
}
int main() {
    int n, m;
    while(~scanf("%d%d", &n, &m)) {
        memset(vis, 0, sizeof(vis));
        memset(nxt, -1, sizeof(nxt));
        memset(f, 0, sizeof(f));
        for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
        sz = cnt = 0;
        for(int i = 1; i <= n; i++) {
            if(a[i] <= m) {
                a[++sz] = a[i];
                if(vis[a[sz]]) a[sz] = vis[a[sz]];
                else {
                    vis[a[sz]] = ++cnt;
                    a[sz] = vis[a[sz]];
                }
            }
        }
        for(int i = 0; i <= sz; i++) {
            for(int j = i + 1; j <= sz; j++) {
                if(nxt[i][a[j]] == -1) nxt[i][a[j]] = j;
            }
        }
        for(int i = 1; i <= cnt + 1; i++) {
            for(int j = 1; j <= cnt + 1; j++) {
                for(int k = 1; k <= cnt + 1; k++) {
                    t[0] = i; t[1] = j; t[2] = k;
                    S = mx = 0;
                    dfs(0, 0, 0);
                    LL tmp = 1;
                    for(int s = 0; s < 3; s++) {
                        if((S & (1 << s))==0&&t[s] == cnt + 1) {
                            tmp *= (LL)(m - cnt);
                        }
                    }
                    f[mx] += tmp;
                }
            }
        }
        printf("%lld %lld %lld %lld\n", f[0], f[1], f[2], f[3]);
    }
    return 0;
}


相关标签: 计数