[动态规划] 黑客的攻击 Hacker's CrackDown Uva 11825
抽象为数学模型就是, 取尽可能多的互不相交的子集 , 使得每一个子集都能覆盖全集#include#include#includeusing namespace std;int n;int P[1000],cover[1000],f[1000];int main(){scanf("%d", &n);for (int i = 0; i < n;i+
·
抽象为数学模型就是, 取尽可能多的互不相交的子集 , 使得每一个子集都能覆盖全集
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
int n;
int P[1000],cover[1000],f[1000];
int main(){
scanf("%d", &n);
for (int i = 0; i < n;i++)
{
int m, x;
scanf("%d", &m);
P[i] == 1 << i;
while (m--)
{
scanf("%d", &x);
P[i] |= (1 << x);
}
}
for (int S = 1; S < n;S++)
{
cover[S] = 0;
for (int i = 0; i < n; i++){
if (S&(1 << i)) cover[S] |= P[i];
}
}
f[0] = 0;
int ALL = (1 << n) - 1;
for (int S = 1; S < n;S++)
{
f[S] = 0;
for (int S0 = S; S0;S0=(S0 - 1) & S)
// 这是最关键的一部, 取子集操作
{
if (cover[S0]==ALL)
{
f[S] = max(f[S], f[S^S0] + 1);
//取出子集的补集+1与最大值比较
}
}
}
printf("%d", f[ALL]);
return 0;
}
更多推荐
所有评论(0)