zoukankan      html  css  js  c++  java
  • 【11.8校内测试】【倒计时2天】【状压DP】【随机化?/暴力小模拟】

    Solution

    数据范围疯狂暗示状压,可是一开始发现状态特别难受。

    将每一层的奇偶性状压,预处理所有状态的奇偶性。每一层的输入代表的其实可以是下一层某个点可以被从这一层哪些点转移到。

    所以枚举每个状态,再枚举下一层转移到哪个点,统计这个点被这个状态更新的话正边和反边分别的奇偶性,转移即可。

    第二层和最后一层单独处理即可。

    Code

    #include<bits/stdc++.h>
    #define mod 998244353
    using namespace std;
    
    int x, dp[2][(1 << 11)], pre[(1 << 11)], up[1 << 11], dn[1 << 11];
    int m, k;
    
    int read () {
        int x = 0, f = 0; char c = getchar ();
        while (!isdigit (c)) f |= (c == '-'), c = getchar ();
        while (isdigit (c)) x = x * 10 + c - '0', c = getchar ();
        return f ? -x : x;
    }
    
    void init() {
        for(int i = 0; i < (1 << k); i ++)
            pre[i] = (i & 1) ^ pre[i >> 1];
    }
    
    int main() {
        freopen("adore.in", "r", stdin);
        freopen("adore.out", "w", stdout);
        scanf("%d%d", &m, &k);
        int sta = 0;
        for(int i = 0; i < k; i ++)    {
            x = read(),    sta |= (x << i);
        }
        dp[0][sta] = 1; init(); 
        int now = 0;
        for(int i = 1; i < m - 2; i ++) {
            now ^= 1;
            memset(dp[now], 0, sizeof(dp[now]));
            memset(up, 0, sizeof(up));
            memset(dn, 0, sizeof(dn));
            for(int u = 0; u < k; u ++)
                for(int v = 0; v < k; v ++) {
                    x = read();
                    up[u] |= (x << v);////反边 u能被那些点更新过来 
                    dn[v] |= (x << u);////正边 
                }
            for(int s = 0; s < (1 << k); s ++)
                if(dp[now ^ 1][s]) {
                    int A = 0, B = 0;
                    for(int j = 0; j < k; j ++)
                        A |= ((pre[s & up[j]]) << j), B |= ((pre[s & dn[j]]) << j);
                    dp[now][A] = (dp[now][A] + dp[now ^ 1][s]) % mod;
                    dp[now][B] = (dp[now][B] + dp[now ^ 1][s]) % mod;
                }
        }
        int st = 0;
        for(int i = 0; i < k; i ++)    x = read(), st |= (x << i);
        int ans = 0;
        for(int s = 0; s < (1 << k); s ++)
            if(!pre[st & s])    ans = (ans + dp[now][s]) % mod;
        printf("%d", ans);
        return 0;
    }

    Solution

    !!!原来是有$n+1$排!!是说为什么每次闪退QAQ

    其实就是小模拟,直接三层for循环找到答案退出即可QAQ这个复杂度太有欺骗性了!!

    其实随机搞更快???

    Code

    #include<bits/stdc++.h>
    using namespace std;
    
    int n, t1, t2, num[6005];
    string s;
    bitset < 12005 > b[6005];
    
    int main() {
        freopen("confess.in", "r", stdin);
        freopen("confess.out", "w", stdout);
        srand(time(0));
        scanf("%d", &n);
        for(int i = 0; i <= n; i ++) {
            cin >> s;
            int len = s.length();
            for(int j = 0; j < len; j ++) {
                int a = s[j] - 33;
                for(int k = 5; k >= 0; k --)if(num[i]<(n<<1))    b[i][++num[i]] = ((a >> k) & 1);
            }
        }
        int cnt;
        while(1) {
            int i = rand() % (n + 1);
            int j = rand() % (n + 1);
            if(i == j) j ++;
            if((b[i] & b[j]).count() >= (n / 2)) {
                if(i > j)    swap(i, j);
                printf("%d %d", i+1, j+1); return 0;
            }
        }
        printf("NO Solution");
        return 0;
    }
  • 相关阅读:
    使用js来执行全屏
    vue多个组件的过渡
    mac笔记本上的工具
    webpack优化技术参考
    VS Code 编译器的调试工具整理
    自定义滑块Vue组件
    Multi-level Multi-select plugin
    cucumber learning : http://www.cnblogs.com/puresoul/category/340832.html
    Opensuse enable sound and mic card
    Shell displays color output
  • 原文地址:https://www.cnblogs.com/wans-caesar-02111007/p/9929774.html
Copyright © 2011-2022 走看看