uva 11825 黑客的攻击 状态dp 典型

来源:互联网 发布:sql select两个表 编辑:程序博客网 时间:2024/06/05 23:50

第一想法是搜索,但有n^n种状态。

本题的数学模型可以是每台电脑和相连的电脑看作一个集合。p1,p2.....pn。要使停止的服务越多。要求从p中选出最多的字集,是每个子集的并集

为n台电脑都有。每个pi可以用整数的二进制位的状态表示。用dp,dp(i)=max{dp(i-j)}+1,i为是否选p1,p2....pn的状态表示,j是i的子集。

实现需要枚举i的子集。

/*uva 11825*/#include <stdio.h>#include <algorithm>#include <string.h>int main(int argc, char const *argv[]){// freopen("input","r",stdin);int n;int q=0;while(scanf("%d",&n),q++,n){int dp[1<<n];int A[1<<n];memset(A,false,sizeof(A));memset(dp,false,sizeof(dp));int p[20];int v=n;for(int i=0;i<n;i++){int m;scanf("%d",&m);p[i]=1<<i;for(int j=0;j<m;j++){int t;scanf("%d",&t);p[i]|=1<<t;}}for(int i=0;i<1<<n;i++){int t=i;for(int j=0;j<n;j++,t=t>>1)//不要写成t>>1if(t & 1)A[i]|=p[j];// printf("%da\n",A[i] );}int s=(1<<n)-1;//一定要加()for(int i=0;i<=s;i++){if(i==0){dp[i]=0;continue;}int j=i;do//枚举子集{if(A[j]==s){// printf("%d\n",j );dp[i]=dp[i]>dp[i & ~j]+1 ? dp[i]:dp[i & ~j]+1;}j=(j-1) & i;}while(j!=i);}printf("Case %d: %d\n",q,dp[s] );}return 0;}



0 0
原创粉丝点击