zoukankan      html  css  js  c++  java
  • P2962 [USACO09NOV]灯Lights [高斯消元+异或方程组 / 折半搜索]

    LightsLights

    节日宴会上,我们有 N(10<=N<=36)盏彩色灯,他们分别从 1 到 N 被标上号码。有 M 条边连接着这些灯,当按下某一盏灯的开关的时候,这盏灯本身以及所有和这盏灯有边相连的灯的开关状态都会发生改变。最开始所有灯都是被关着的,问需要至少按下多少开关,才可以把所有灯打开。

    1N361 le N le 36.


    color{red}{正解部分}

    1:方法 1:
    这道题目 建立异或方程组, 对自由元的状态进行枚举, 解出方程, 从中选出最优解.

    2:方法 2:
    折半搜索,

    将原来的序列分为 N/2N/2NN/2N - N/2 两部分,

    始状态 搜出操作前半部分能得到的所有状态, 记为 S1S_1,
    末状态 倒搜出操作后半部分能得到的所有状态, 记为 S2S_2,

    S2S_2 中查找每个 S1S_1 中的元素, 找到则更新答案 .


    color{red}{实现部分}

    1:方法 1:

    .color{red}{待填坑 .}

    2:方法 2:

    注意 DFS_1DFS\_1DFS_2DFS\_2 不要搞混 .
    code with bug

    使用状态压缩:

    • 每个操作都可以使用二进制状态表示, 使用时直接对状态异或就可以方便地改变状态.
    • 使用 mapmap 保存状态.
    • 注意自环 .
    #include<bits/stdc++.h>
    #define reg register
    typedef long long ll;
    
    const int maxn = 300005;
    
    int N;
    int M;
    int Ans;
    
    ll Opt[maxn];
    
    std::map <ll, int> Mp;
    
    void DFS(int k, int cnt, ll zt){
            if(k == N+1){
                    if(Mp.count(zt)) Ans = std::min(Ans, cnt + Mp[zt]);
                    return ;
            }
            DFS(k+1, cnt+1, zt^Opt[k]), DFS(k+1, cnt, zt);
    }
    
    int main(){
            scanf("%d%d", &N, &M);
            for(reg int i = 1; i <= M; i ++){
                    int a, b;
                    scanf("%d%d", &a, &b);
                    Opt[a] |= (1ll<<b-1), Opt[b] |= (1ll<<a-1);
            }
            for(reg int i = 1; i <= N; i ++) Opt[i] |= (1ll<<i-1);
            int Half = N >> 1;
            for(reg int i = 0; i < 1<<Half; i ++){
                    int cnt = 0;
                    ll zt = 0;
                    for(reg int j = 1; j <= Half; j ++)
                            if((1ll<<j-1) & i) cnt ++, zt ^= Opt[j];
                    if(Mp.count(zt)) Mp[zt] = std::min(Mp[zt], cnt);
                    else Mp[zt] = cnt;
            }
            Ans = 0x3f3f3f3f;
            DFS(Half+1, 0, (1ll<<N)-1);
            printf("%d
    ", Ans);
            return 0;
    }
    
  • 相关阅读:
    非常实用的php各种文件操作函数
    两个自用的Dota2 自走棋辅助工具:阵容模拟器与UI Mod插件
    Scratch 数字游戏
    初识Scratch 3.0
    何时重头来
    cocos2d-x 3.0 Armature jsb 初体验
    cocosbuilder中的Callbacks和sound effects
    cocos2dx js文件加密为jsc文件
    cocos2dx jsb 在IOS与安卓下的一些不同之处
    安卓打包记录
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822548.html
Copyright © 2011-2022 走看看