UVA 11775 Unique Story(LCS [LIS] + BIT)

来源:互联网 发布:金蝶免费进销存软件 编辑:程序博客网 时间:2024/05/19 19:32

题意:

,n1000

分析:

,dp,dp[i][j]:=a[i],b[j]
,,
,(2n+2m2),

这里写图片描述


O(nmlognlogm)

1. dp[i][j]:=a[i],b[j]
a[i]==b[j],dp[i][j]=dp[x][y](x<i,y<j)+2
,
dp[i][j]=sum(i,j1)+sum(i1,j)sum(i1,j1)+2,(i,j)
ans=sum(n,m)
O(nmlognlogm)

代码:

////  Created by TaoSama on 2015-11-22//  Copyright (c) 2015 TaoSama. All rights reserved.////#pragma comment(linker, "/STACK:1024000000,1024000000")#include <algorithm>#include <cctype>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iomanip>#include <iostream>#include <map>#include <queue>#include <string>#include <set>#include <vector>using namespace std;#define pr(x) cout << #x << " = " << x << "  "#define prln(x) cout << #x << " = " << x << endlconst int N = 2e3 + 10, INF = 0x3f3f3f3f, MOD = 10000007;int n, m, u[N], v[N];int b[N][N], dp[N][N];void add(int &x, int y) {    x = x + y + MOD;    while(x >= MOD) x -= MOD;}void add(int x, int y, int v) {    for(int i = x; i <= n; i += i & -i)        for(int j = y; j <= m; j += j & -j)            add(b[i][j], v);}int sum(int x, int y) {    int ret = 0;    for(int i = x; i; i -= i & -i)        for(int j = y; j; j -= j & -j)            add(ret, b[i][j]);    return ret;}int cnt = 0;map<string, int> mp;int ID(string &s) {    if(mp.count(s)) return mp[s];    mp[s] = ++cnt;    return cnt;}void handle(int &n, string &s, int *u) {    n = 0; s += 'A';    string tmp;    for(int i = 0; i < s.size(); ++i) {        if(isalpha(s[i])) {            if(tmp.size()) {                u[++n] = ID(tmp);                tmp.clear();            }        }        tmp += s[i];    }}int two[2005] = {1};string s, t;int main() {#ifdef LOCAL    freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);//  freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);#endif    ios_base::sync_with_stdio(0);    int T; cin >> T;    int kase = 0;    for(int i = 1; i <= 2000; ++i) two[i] = two[i - 1] * 2 % MOD;    while(T--) {        cin >> s >> t;        cnt = 0; mp.clear();        handle(n, s, u);        handle(m, t, v);        memset(dp, 0, sizeof dp);        memset(b, 0, sizeof b);        for(int i = 1; i <= n; ++i) {            for(int j = 1; j <= m; ++j) {                if(u[i] != v[j]) continue;                add(dp[i][j], sum(i, j - 1) + sum(i - 1, j)                    - sum(i - 1, j - 1) + 2);                add(i, j, dp[i][j]);            }        }        int ans = ((two[n] + two[m] - 2 - sum(n, m)) % MOD + MOD) % MOD;        printf("Case %d: %d\n", ++kase, ans);    }    return 0;}

O(nm)

,,
2. dp[i][j]:=a[i],b[j]
a[i]==b[j],+a[i],b[j]+a[i],b[j]
dp[i][j]=2dp[i1][j1]+2
a[i]!=b[j],,(i,j)
dp[i][j]=dp[i][j1]+dp[i1][j]dp[i1][j1]
ans=dp[n][m]
O(nm)

代码:

////  Created by TaoSama on 2015-11-22//  Copyright (c) 2015 TaoSama. All rights reserved.////#pragma comment(linker, "/STACK:1024000000,1024000000")#include <algorithm>#include <cctype>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iomanip>#include <iostream>#include <map>#include <queue>#include <string>#include <set>#include <vector>using namespace std;#define pr(x) cout << #x << " = " << x << "  "#define prln(x) cout << #x << " = " << x << endlconst int N = 2e3 + 10, INF = 0x3f3f3f3f, MOD = 10000007;int n, m, u[N], v[N];int b[N][N], dp[N][N];void add(int &x, int y) {    x = x + y + MOD;    while(x >= MOD) x -= MOD;}int cnt = 0;map<string, int> mp;int ID(string &s) {    if(mp.count(s)) return mp[s];    mp[s] = ++cnt;    return cnt;}void handle(int &n, string &s, int *u) {    n = 0; s += 'A';    string tmp;    for(int i = 0; i < s.size(); ++i) {        if(isalpha(s[i])) {            if(tmp.size()) {                u[++n] = ID(tmp);                tmp.clear();            }        }        tmp += s[i];    }}int two[2005] = {1};string s, t;int main() {#ifdef LOCAL    freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);//  freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);#endif    ios_base::sync_with_stdio(0);    int T; cin >> T;    int kase = 0;    for(int i = 1; i <= 2000; ++i) two[i] = two[i - 1] * 2 % MOD;    while(T--) {        cin >> s >> t;        cnt = 0; mp.clear();        handle(n, s, u);        handle(m, t, v);        memset(dp, 0, sizeof dp);        for(int i = 1; i <= n; ++i) {            for(int j = 1; j <= m; ++j) {                if(u[i] == v[j])                    add(dp[i][j], 2 * dp[i - 1][j - 1] + 2);                else                    add(dp[i][j], dp[i][j - 1] + dp[i - 1][j] - dp[i - 1][j - 1]);            }        }        int ans = ((two[n] + two[m] - 2 - dp[n][m]) % MOD + MOD) % MOD;        printf("Case %d: %d\n", ++kase, ans);    }    return 0;}

O(nlogn)

LCSLIS
a[i],b[j],,,LIS,
3. dp[i]:=a[i]
BIT
ans=ni=1dp[i]
O(nlogn)

代码:

////  Created by TaoSama on 2015-11-22//  Copyright (c) 2015 TaoSama. All rights reserved.////#pragma comment(linker, "/STACK:1024000000,1024000000")#include <algorithm>#include <cctype>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iomanip>#include <iostream>#include <map>#include <queue>#include <string>#include <set>#include <vector>using namespace std;#define pr(x) cout << #x << " = " << x << "  "#define prln(x) cout << #x << " = " << x << endlconst int N = 2e3 + 10, INF = 0x3f3f3f3f, MOD = 10000007;int n, m, c, a[N];int b[N], dp[N];int cnt = 0;map<string, int> mp;int ID(string &s) {    if(mp.count(s)) return mp[s];    mp[s] = ++cnt;    return -1;}void add(int &x, int y) {    x += y;    if(x < 0) x += MOD;    else if(x >= MOD) x -= MOD;}void update(int i, int v) {    for(; i <= cnt; i += i & -i) add(b[i], v);}int sum(int i) {    int ret = 0;    for(; i; i -= i & -i) add(ret, b[i]);    return ret;}void handle(int &n, string &s, bool flag) {    n = c = 0; s += 'A';    string tmp; tmp += s[0];    for(int i = 1; i < s.size(); ++i) {        if(isalpha(s[i])) {            ++n;            int id = ID(tmp);            if(flag && ~id) a[++c] = id;            tmp.clear();        }        tmp += s[i];    }}int two[2005] = {1};string s, t;int main() {#ifdef LOCAL    freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);//  freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);#endif//  ios_base::sync_with_stdio(0);    int T; cin >> T;    int kase = 0;    for(int i = 1; i <= 2000; ++i) two[i] = two[i - 1] * 2 % MOD;    while(T--) {        cin >> s >> t;        cnt = 0; mp.clear();        handle(n, s, false);        handle(m, t, true);        memset(dp, 0, sizeof dp);        memset(b, 0, sizeof b);        for(int i = 1; i <= c; ++i) {            dp[i] = sum(a[i]) + 1;            update(a[i], dp[i]);        }        int ans = ((two[n] + two[m] - 2 - 2 * sum(cnt)) % MOD + MOD) % MOD;        printf("Case %d: %d\n", ++kase, ans);    }    return 0;}
0 0
原创粉丝点击