POJ _2436--Disease Management

 

1.使用algorithm中的next_permutation函数

本题主要是使用位与运算,同时需要组合和枚举;先枚举每一种k类疾病的组合,对此组合然后与每一头牛进行或运算,若在已有的集合中不会增添新的疾病,则数量加一,以此类推,求出最大的即为结果

对于位运算,最低位为1,次位为2,...,第i低位为2^(i-1),若第i位表示的疾病在集合中,则将集合表示成的数加上2^(i-1);如此则可以生成一个数代表整个集合。

须注意,next_permutation(first,last)生成的是由小到大的集合

#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int bin[15] = {1,2,4,8,16,32,64,128,256,512,/ 1024,2048,4096,8192,16384}; int flag[15],cows[1005]; int maxc,n,d,k,temp; int solve() { int i; do { int num=0,temp=0; for(i=0;i<d;i++) if(flag[i]) temp+=bin[i]; for(i=0;i<n;i++) { if(temp==(temp|cows[i])) num++; } maxc=maxc>num?maxc:num; }while(next_permutation(flag,flag+d)); return 0; } int main() { while(scanf("%d%d%d",&n,&d,&k)==3) { int p,i,t; memset(flag,0,sizeof(flag)); for(i=d-1;i>=d-k;i--) flag[i]=1; maxc=0; for(i=0;i<n;i++) { scanf("%d",&p); cows[i]=0; while(p--) { scanf("%d",&t); cows[i]+=bin[t-1]; } } solve(); printf("%d/n",maxc); } return 0; }

 

2.生成由大到小的集合,与id codes相反

////回溯法生成固定数目的排列效率太低,因此使用递推法生成排列 #include<stdio.h> #include<string.h> int bin[15] = {1,2,4,8,16,32,64,128,256,512,/ 1024,2048,4096,8192,16384}; int flag[15],cows[1005]; int max,n,d,k,temp; int search() { int i; for(i=0;i<d-1;i++) { if(flag[i]==1&&flag[i+1]==0) return i; } return -1; } int solve() { int i,j,t,num,temp; while(1) { num=0;temp=0; for(i=0;i<d;i++) { if(flag[i]) temp+=bin[i]; } for(i=0;i<n;i++) { if(temp==(temp|cows[i])) num++; } max=max>num?max:num; t=search(); num=0; if(t!=-1) { for(i=0;i<t;i++) { if(flag[i]) { num++; flag[i]=0; } } flag[t]=0;flag[t+1]=1; for(i=0;i<num;i++) flag[i]=1; } else break; } return 0; } int main() { while(scanf("%d%d%d",&n,&d,&k)==3) { int p,i,t; for(i=0;i<k;i++) flag[i]=1; for(i=k;i<d;i++) flag[i]=0; max=0; for(i=0;i<n;i++) { scanf("%d",&p); cows[i]=0; while(p--) { scanf("%d",&t); cows[i]+=bin[t-1]; } } solve(); printf("%d/n",max); } return 0; }

你可能感兴趣的:(POJ _2436--Disease Management)