题目
题解
_ (:зゝ∠) _这题的数学模型也是很厉害,不过知道数学模型之后就好做了,学习到的一个技巧是如何枚举子集(比如说1011的子集枚举)
代码
//QWsin
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=20;
int n,a[maxn],sum[(1<<16)+10],dp[(1<<16)+10];
int kase=0;
inline void print(int ans){printf("Case %d: %d\n",++kase,ans);}
inline void solve()
{
for(int i=0,m,x;i<n;++i)
{
a[i]=(1<<i);scanf("%d",&m);
while(m--) scanf("%d",&x),a[i]|=(1<<x);
}
for(int i=0;i<(1<<n);++i)
{
sum[i]=0;
for(int j=0;j<n;++j) if(i & (1<<j)) sum[i]|=a[j];
}
int ALL=(1<<n)-1,ans=0;
for(int i=1;i<(1<<n);++i)
{
dp[i]=0;
for(int j=i;j;j=(j-1)&i)
if(sum[j]==ALL) dp[i]=max(dp[i],dp[i^j]+1);
ans=max(ans,dp[i]);
}
print(ans);
}
int main()
{
while(scanf("%d",&n)==1&&n) solve();
return 0;
}

本文针对UVa11825题目提供了一种解决方案,通过使用位运算来枚举子集并求解最大子集覆盖问题。文章详细介绍了如何构建数学模型,并附带了完整的代码实现。
1415

被折叠的 条评论
为什么被折叠?



