zoukankan      html  css  js  c++  java
  • Hackers' Crackdown UVA

    给出n个电脑,每个电脑连着n个服务,然后每个电脑都连着m个邻电脑,如果当前的电脑某个服务被断开了,相邻的电脑的服务也会被断开,每个电脑都只能操作一次,问你最多可以让多少种服务被断开。一种服务被断开的条件就是存在一个破坏第i个电脑的集合,这个集合扩散出去的集合是全集(......语文真的是......讲不出来)

    先把每个电脑和邻电脑的状态记录下来,把这个看成一个集合,然后那么我现在的问题就变成了用一些电脑的集合并起来使他变成全集。

    现在把n个电脑的可能状态全部枚举出来,然后看当前这些电脑最多可以影响多少电脑,把这种状态记录下来,然后在开始dp

    dp[电脑的所有可能状态] = 当前状态可以获得的最大方案数

    所以我现在可以枚举破坏电脑的状态,然后去找这个状态的子集,如果我的子集可以影响的范围是全集的话,那么我的dp状态就是dp[i] = max(dp[i], dp[i^j]+1),表示我可能从补集+1或者自己原本的最大值。

    #include<map>
    #include<ctime>
    #include<cmath>
    #include<stack>
    #include<queue>
    #include<string>
    #include<vector>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define lowbit(x) (x & (-x))
    
    typedef unsigned long long int ull;
    typedef long long int ll;
    const double pi = 4.0*atan(1.0);
    const int inf = 0x3f3f3f3f;
    const int maxn = 1 << 17;
    const int maxm = 40000;
    const int mod = 1000000007;
    using namespace std;
    
    int n, m, tol;
    int dp[maxn];
    int state[maxn];
    int num[20];
    
    void init() {
        memset(dp, 0, sizeof dp);
        memset(num, 0, sizeof num);
        memset(state, 0, sizeof state);
    }
    
    int main() {
        int cas = 1;
        while(scanf("%d", &n), n) {
            init();
            for(int i=0; i<n; i++) {
                num[i] = 1 << i;
                scanf("%d", &m);
                while(m--) {
                    int tmp;
                    scanf("%d", &tmp);
                    num[i] |= (1 << tmp);
                }
            }
            tol = 1 << n;
            for(int i=0; i<tol; i++) {
                state[i] = 0;
                for(int j=0; j<n; j++) {
                    if(i & (1 << j)) {
                        state[i] |= num[j];
                    }
                }
            }
            for(int i=0; i<tol; i++) {
                for(int j=i; j; j=(j-1) & i) {
                    if(state[j] == tol - 1) {
                        dp[i] = max(dp[i], dp[i^j] + 1);
                    }
                }
            }
            printf("Case %d: %d
    ", cas++, dp[tol-1]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    联想 Vibe Shot(Z90-3) 免recovery 获取ROOT权限 救砖 VIBEUI V3.1_1625
    联想 Z5S(L78071)免解锁BL 免rec 保留数据 ROOT Magisk Xposed 救砖 ZUI 10.5.370
    联想 Z5(L78011) 免解锁BL 免rec 保留数据 ROOT Magisk Xposed 救砖 ZUI 10.5.254
    联想 S5 Pro(L78041)免解锁BL 免rec 保留数据 ROOT Magisk Xposed 救砖 ZUI 5.0.123
    第二阶段 冲刺八
    第二阶段 冲刺七
    第二阶段 冲刺六
    第二阶段 冲刺五
    代码大全阅读笔记03
    学习进度十二
  • 原文地址:https://www.cnblogs.com/Jiaaaaaaaqi/p/10296759.html
Copyright © 2011-2022 走看看