您的位置:首页 > 产品设计 > UI/UE

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

2017-05-17 21:41 387 查看

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:

1≤x 1 ,x 2 ,x 3 ≤m ;
The length of longest common subsequence of

and X 
is exactly k .
Note:


is a subsequence of v 
if and only if u 
can be obtained by removing some of the entries from

(possibly none).

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  .

1≤n≤200 
1≤m,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

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: