zoukankan      html  css  js  c++  java
  • loj6043 「雅礼集训 2017 Day7」蛐蛐国的修墙方案

    传送门:https://loj.ac/problem/6043

    【题解】

    我们考虑这是个置换,所以一定形成了很多不相交的环。

    对于每个环,我们只能选一段、不选、选一段、不选这样交替下去。

    显然只有偶环是有解的,所以只考虑偶环。

    每个偶环有2种方案(第一个选,第一个不选),直接枚举是O(2^(n/2))的,复杂度接受不了。

    我们发现,2元环的左括号一定放在前面更优(更容易形成括号序列),所以贪心放,剩下的最小是4元环,枚举即可,所以复杂度是O(2^(n/4))。

    写个dfs然后发现常数太大。。。(还是过了)

    # include <vector>
    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 200 + 10;
    const int mod = 1e9+7;
    
    # define RG register
    # define ST static
    
    int n, p[M], ans[M];
    int h[M][M], hn[M], a[M], an;
    int m; 
    
    int head[M], nxt[M], to[M], tot = 0;
    inline void add(int u, int v) {
        ++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v;
    }
    inline void adde(int u, int v) {
        add(u, v), add(v, u);
    }
    
    bool vis[M]; 
    inline void dfs(int x, int fa) {
        if(vis[x]) return ; 
        vis[x] = 1; 
        a[++an] = x;
        for (int i=head[x]; i; i=nxt[i]) 
            if(to[i] != fa) dfs(to[i], x); 
    }
    
    inline void solve(int x) {
        an = 0;
        dfs(x, 0);
        if(an == 2) {
            if(a[1] < a[2]) ans[a[1]] = 1;
            else ans[a[2]] = 1;
        } else {
            ++m; hn[m] = an; 
            for (int i=1; i<=an; ++i) h[m][i] = a[i];
        }
    }
    
    inline bool chk() {
        int sum = 0;
        for (int i=1; i<=n; ++i) {
            sum = sum + (ans[i] ? 1 : -1);
            if(sum < 0) return false;
        }
        for (int i=1; i<=n; ++i) putchar(ans[i] ? '(' : ')'); 
        puts("");
        return true;
    }
    
    bool ok;
    inline void gans(int x) {
        if(ok) return ; 
        if(x == m + 1) {
            if (chk()) ok = 1;
            return ;
        }
        for (int i=1; i<=hn[x]; ++i) ans[h[x][i]] = (i&1);
        gans(x+1);
        for (int i=1; i<=hn[x]; ++i) ans[h[x][i]] ^= 1;
        gans(x+1);
    }
    
    int main() {
        freopen("c.in", "r", stdin);
        freopen("c.out", "w", stdout); 
        cin >> n;
        for (int i=1; i<=n; ++i) scanf("%d", &p[i]); 
        for (int i=1; i<=n; ++i) adde(i, p[i]);
        for (int i=1; i<=n; ++i) if(!vis[i]) solve(i); 
    //    for (int i=1; i<=m; ++i, puts("
    "))
    //        for (int j=1; j<=hn[i]; ++j)
    //            printf("%d ", h[i][j]); 
        gans(1); 
        return 0;
    }
    View Code
  • 相关阅读:
    How to install VXDIAG Honda, Toyota and JLR SDD software
    16% off MPPS V16 ECU tuning tool for EDC15 EDC16 EDC17
    Cummins INSITE locked and ask for verification code
    How to use BMW Multi Tool 7.3 to replace lost key for BMW X1
    Bleed Brake Master Cylinder with Intelligent Tester IT2
    Porsche Piwis Tester II “No VCI has been detected”,how to do?
    Creader VIII VS. Creader VII+
    How to solve GM MDI cannot complete the installation
    汽车OBD2诊断程序开发 (原文转载,思路很清晰!)
    汽车节温器单片机开发思路
  • 原文地址:https://www.cnblogs.com/galaxies/p/loj6043.html
Copyright © 2011-2022 走看看