zoukankan      html  css  js  c++  java
  • HDU

    HDU - 5330

    感觉这种dp和子集和dp差不多, 有点难想到。

    dp[ i ][ S ][ j ]  表示最低的 i 位和 S最低的 i 位一样的所有串中, 和 S 的距离为 j 的有多少个。

    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #pragma GCC optimize(4)
    #include<bits/stdc++.h>
    #define LL long long
    #define LD long double
    #define ull unsigned long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ALL(x) (x).begin(), (x).end()
    #define fio ios::sync_with_stdio(false); cin.tie(0);
    
    using namespace std;
    
    const int N = 2e5 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = (int)1e9 + 7;
    const double eps = 1e-8;
    const double PI = acos(-1);
    
    template<class T, class S> inline void add(T &a, S b) {a += b; if(a >= mod) a -= mod;}
    template<class T, class S> inline void sub(T &a, S b) {a -= b; if(a < 0) a += mod;}
    template<class T, class S> inline bool chkmax(T &a, S b) {return a < b ? a = b, true : false;}
    template<class T, class S> inline bool chkmin(T &a, S b) {return a > b ? a = b, true : false;}
    
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    
    int n, m, up;
    int dp[2][N][23];
    int c[N];
    int (*f)[23] = dp[0];
    int (*g)[23] = dp[1];
    int v[12];
    LL ans[23];
    
    char s[20];
    
    void init() {
        memset(ans, 0, sizeof(ans));
        for(int i = 0; i < up; i++) {
            c[i] = 0;
        }
        for(int i = 0; i < up; i++) {
            for(int j = 0; j <= 2 * m; j++) {
                f[i][j] = 0;
            }
        }
    }
    
    int main() {
        int T; scanf("%d", &T);
        while(T--) {
            scanf("%d%d", &n, &m);
            up = 1;
            for(int i = 1; i <= m; i++) {
                up = up * 3;
            }
            init();
            for(int i = 0; i < n; i++) {
                int val = 0;
                scanf("%s", s);
                for(int j = 0; j < m; j++) {
                    val = val * 3 + (s[j] - '0');
                }
                f[val][0]++;
                c[val]++;
            }
            for(int i = 0; i < m; i++) {
                swap(f, g);
                for(int mask = 0; mask < up; mask++) {
                    for(int j = 0, k = mask; j < m; j++, k /= 3) {
                        v[j] = k % 3;
                    }
                    int pmask0 = 0, pmask1 = 0, pmask2 = 0;
                    for(int j = m - 1; j >= 0; j--) {
                        pmask0 *= 3; pmask1 *= 3; pmask2 *= 3;
                        if(j == i) {
                            pmask0 += 0;
                            pmask1 += 1;
                            pmask2 += 2;
                        } else {
                            pmask0 += v[j];
                            pmask1 += v[j];
                            pmask2 += v[j];
                        }
                    }
                    for(int j = 0; j <= 2 * m; j++) {
                        f[mask][j] = 0;
                        if(v[i] == 0) {
                            f[mask][j] += g[pmask0][j];
                            if(j >= 1) f[mask][j] += g[pmask1][j - 1];
                            if(j >= 2) f[mask][j] += g[pmask2][j - 2];
                        }
                        else if(v[i] == 1) {
                            if(j >= 1) f[mask][j] += g[pmask0][j - 1];
                            f[mask][j] += g[pmask1][j];
                            if(j >= 1) f[mask][j] += g[pmask2][j - 1];
                        }
                        else {
                            if(j >= 2) f[mask][j] += g[pmask0][j - 2];
                            if(j >= 1) f[mask][j] += g[pmask1][j - 1];
                            f[mask][j] += g[pmask2][j];
                        }
                    }
                }
            }
            for(int mask = 0; mask < up; mask++) {
                ans[0] += 1LL * c[mask] * (c[mask] - 1);
                for(int j = 1; j <= 2 * m; j++) {
                    ans[j] += 1LL * c[mask] * f[mask][j];
                }
            }
            for(int i = 0; i <= 2 * m; i++) {
                printf("%lld
    ", ans[i] / 2);
            }
        }
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    List of the best open source software applications
    Owin对Asp.net Web的扩展
    NSwag给api加上说明
    'workspace' in VS Code
    unable to find valid certification path to requested target
    JMeter的下载以及安装使用
    exception disappear when forgot to await an async method
    Filter execute order in asp.net web api
    记录web api的request以及response(即写log)
    asp.net web api的源码
  • 原文地址:https://www.cnblogs.com/CJLHY/p/11308629.html
Copyright © 2011-2022 走看看