zoukankan      html  css  js  c++  java
  • P2622 关灯问题II

    题目描述

    现有n盏灯,以及m个按钮。每个按钮可以同时控制这n盏灯——按下了第i个按钮,对于所有的灯都有一个效果。按下i按钮对于第j盏灯,是下面3中效果之一:如果a[i][j]为1,那么当这盏灯开了的时候,把它关上,否则不管;如果为-1的话,如果这盏灯是关的,那么把它打开,否则也不管;如果是0,无论这灯是否开,都不管。

    现在这些灯都是开的,给出所有开关对所有灯的控制效果,求问最少要按几下按钮才能全部关掉。

    输入输出格式

    输入格式:

    前两行两个数,n m

    接下来m行,每行n个数,a[i][j]表示第i个开关对第j个灯的效果。

    输出格式:

    一个整数,表示最少按按钮次数。如果没有任何办法使其全部关闭,输出-1

    输入输出样例

    输入样例#1: 
    3
    2
    1 0 1
    -1 1 0
    输出样例#1: 
    2

    说明

    对于20%数据,输出无解可以得分。

    对于20%数据,n<=5

    对于20%数据,m<=20

    上面的数据点可能会重叠。

    对于100%数据 n<=10,m<=100

    Solution:

      本题状压dp水题

      定义$f[j]$表示当前灯的状态为$j$的最小花费,初始状态$f[0]=0$,目标状态$f[(1<<n)-1]$($0$为开,$1$为关)。

      用$a_i,b_i$记录下每个按钮的开关效果,然后跑最短路,转移时就二进制捣鼓一下。

      具体来说,若$(i,j)$输入的$x==1$则$a_i|=1<<j-1$,若输入的$x==-1$则$b_i|=1<<j-1$。

      转移时当前状态$sta$转移为$(sta|a_i)&(~b_i)$就能做到灯的开关变换了。

    代码:

    /*Code by 520 -- 10.16*/
    #include<bits/stdc++.h>
    #define il inline
    #define ll long long
    #define RE register
    #define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
    #define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
    using namespace std;
    const int N=105;
    int n,m,a[N],b[N],f[1<<21];
    bool vis[1<<21];
    queue<int>q;
    
    int main(){
        ios::sync_with_stdio(0);
        cin>>n>>m; int x,lim=(1<<n)-1;
        For(i,1,m) For(j,1,n) {
            cin>>x;
            if(x==1) a[i]|=(1<<j-1);
            if(x==-1) b[i]|=(1<<j-1);
        }
        memset(f,0x3f,sizeof(f));
        f[0]=0;q.push(0);
        while(!q.empty()){
            int u=q.front();q.pop();vis[u]=0;
            For(i,1,m) {
                int sta=(u|a[i])&(~b[i]);
                if(f[sta]>f[u]+1) {
                    f[sta]=f[u]+1;
                    if(!vis[sta]) vis[sta]=1,q.push(sta);
                }
            }
        }
        cout<<(f[lim]==0x3f3f3f3f?-1:f[lim]);
        return 0;
    }
  • 相关阅读:
    【转】 java中Class对象详解和类名.class, class.forName(), getClass()区别
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
    107. Binary Tree Level Order Traversal II
    109. Convert Sorted List to Binary Search Tree
    108. Convert Sorted Array to Binary Search Tree
    110. Balanced Binary Tree
    STL容器迭代器失效问题讨论
    113. Path Sum II
    112. Path Sum
  • 原文地址:https://www.cnblogs.com/five20/p/9853076.html
Copyright © 2011-2022 走看看