zoukankan      html  css  js  c++  java
  • 黑客的攻击 Hacker‘s crackdown UVA11825 状态压缩动态规划

    题目的意思是有n台服务器运行着n类程序,一个黑客有n中类的病毒,最多每台服务器可以放一种病毒,但是相邻的服务器会感染同种病毒,只暂停一种服务,问能够暂停的程序的最大种数。

    解决的方法是,用位表示集合,问题的答案相当于是求出最多集合的组合,组合内的集合并集是全集。求这些组合最大的数目。转移方程式f[s]={f[s^s0],s0这种组合内的集合并集是全集}+1.

    这里涉及到一些集合的操作:

    或运算,将元素加入到集合之中。

    枚举集合的所有组合的可能性:

    for(int i=0;i<(1<<n);i++)
    {
        for(int j=0;j<n;j++)
       {
            if(i&(1<<n))cover[i]=cover[i]|s[j];
        }
    }

    枚举集合s的所有子集

    for(int i=s;i>0;i=(i-1)&s)
    {
        //insert code
    }

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define MAXN 1<<17
    int cover[MAXN];
    int s[20];
    int f[MAXN];
    int main()
    {
    	int n;
    	int kas=0;
    	while(scanf("%d",&n),n)
    	{
    		memset(s,0,sizeof(s));
    		for(int i=0;i<n;i++)
    		{
    			int m;cin>>m;
    			s[i]=s[i]|(1<<i);
    			for(int j=0;j<m;j++)
    			{
    				int t;cin>>t;
    				s[i]=s[i]|(1<<t);
    			}
    		}
    		memset(cover,0,sizeof(cover));
    		for(int i=0;i<(1<<n);i++)
    		{
                           for(int j=0;j<n;j++)
    		       {
    			       if(i&(1<<j))cover[i]=cover[i]|s[j];
    		       }
    		}
    		memset(f,0,sizeof(f));
    		for(int i=0;i<(1<<n);i++)
    		{
    			for(int j=i;j>0;j=(j-1)&i)
    			{
    				if(cover[j]==(1<<n)-1)
    				{
    					f[i]=max(f[i],f[i^j]+1);
    				}
    			}
    		}
    		printf("Case %d: %d
    ",++kas,f[(1<<n)-1]);
    	}
    }
    


     

  • 相关阅读:
    互联网与局域网(四)
    Socket介绍(五)
    HttpClient(七)
    TCP协议与HTTP协议区别
    TCP连接的三次握手
    context-param和init-param区别
    【HPU】[1736]老王修马路(二)
    【HPU】[1735]老王修马路(一)
    【HPU】[1734]老王修公园
    【HPU】[1733]神奇的数字9
  • 原文地址:https://www.cnblogs.com/jackwuyongxing/p/3366473.html
Copyright © 2011-2022 走看看