zoukankan      html  css  js  c++  java
  • USACO45 lights 电灯(折半搜索)

    刚刚上一篇博客才D了队长一发,心里虚的慌......万分感谢队长给讲折半搜索!!听说这题可以高斯消元(可是我不会...貌似折半我也不会)

    这题呢,一想到就是爆搜啦,然而,爆搜2^35必跪,折半搜索,就让他变成了2^17+2^18,这下明白一点了吧,然后假设现在要从全灭到全开,状压一下就是一个LL的数了,然后从00000~10101(假设嘛)我们只按左边的按钮,11111~01010只按右边的,那加起来不就是答案啦。

    #include<map>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    LL Bin[40];
    int cnt,mn;
    LL p[40],ed;//状压,p[i]代表假如我按i,会对那些造成影响就在相应位上记为1
    bool half;
    map<LL,int>f;
    void dfs(int x,LL now,int d)
    {
        if(x==cnt+1)
        {
            if(now==ed)mn=min(mn,d);//到达 
            else
            {
                if(half==false)//第一次,记录到达该状态的最优方案 
                {
                    int c=f[now];
                    if(c==0||c>d)f[now]=d;
                }
                else //第二次,看看我和其他合并能否到达最终状态 
                {
                    int c=f[ed-now];
                    if(c!=0)mn=min(mn,c+d);
                }
            }
            return ;
        }
        dfs(x+1,now,d);//穷举状态 
        dfs(x+1,now^p[x],d+1);
    }  
    int main()  
    {
        int n,m,x,y;
        scanf("%d%d",&n,&m);
        p[1]=Bin[1]=1;for(int i=2;i<=n+1;i++)p[i]=Bin[i]=Bin[i-1]*2;  
        ed=Bin[n+1]-1;//结束状态就是全为1 
        
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            p[x]+=Bin[y];p[y]+=Bin[x];//记录所影响的 
        }
        
        mn=2147483647;
        half=false;cnt=n/2;dfs(1,0,0);//折半搜索 
        half=true;cnt=n;dfs(n/2+1,0,0);
        printf("%d
    ",mn);
        return 0;  
    }  
  • 相关阅读:
    打开服务器的文档
    笔记
    centos6.5 编译openssl-1.1.1k
    搭建自己的低代码平台
    防火墙ACL配置自动化
    防火墙ACL配置自动化
    【树莓派】读取新大陆(newland)USB条码扫描器数据
    解决eclipse或sts闪退的办法(转)
    浅谈数据库迁移类项目功能测试的基本思路
    ATM取款机优化需求的用例设计
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/7725535.html
Copyright © 2011-2022 走看看