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

来源:互联网 发布:点卡商城源码 编辑:程序博客网 时间:2024/05/18 22:43

Longest Common Subsequence

Accepted : 11 Submit : 105Time 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 31 2 25 31 2 3 2 1

Sample Output

1 14 11 10 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;}


原创粉丝点击