ZOJ2898【折半搜索】
2024-10-09 01:01:05
题意:
给出一系列值和对应的陷阱,对于陷阱如果存在两个就抵消,求价值最大。
思路:
折半枚举,利用异或
#include <bits/stdc++.h>
using namespace std;
typedef long long LL; int v[30],k[30];
int trap[30][60],n,ans;
map<LL,int>mp;
map<LL,int>::iterator it;
int main()
{
while(~scanf("%d",&n))
{
ans=0;
mp.clear();
for(int i=0;i<n;i++)
{
scanf("%d",&v[i]);
scanf("%d",&k[i]);
for(int j=0;j<k[i];j++)
scanf("%d",&trap[i][j]);
}
int half=n/2;
int sz=(1<<half);
for(int i=0;i<sz;i++)
{
LL x=0;
int val=0;
for(int j=0;j<half;j++)
{
if(i&(1<<j))
{
for(int t=0;t<k[j];t++)
x^=(LL)(1LL<<trap[j][t]);
val+=v[j];
}
}
it=mp.find(x);
if(it!=mp.end())
{
int last=it->second;
if(last<val)
mp[x]=val;
}
else
mp[x]=val;
}
int res=n-half;
sz=(1<<res);
for(int i=0;i<sz;i++)
{
LL x=0;
int val=0;
for(int j=0;j<res;j++)
{
if(i&(1<<j))
{
for(int t=0;t<k[j+half];t++)
x^=(LL)(1LL<<trap[j+half][t]);
val+=v[j+half];
}
}
LL y=(0LL^x);
it=mp.find(y);
if(it!=mp.end())
{
int now=it->second;
val+=now;
ans=max(ans,val);
}
}
printf("%d\n",ans);
}
return 0;
}
最新文章
- jQuery解决iframe高度自适应代码
- Android 程序打包及签名
- Java 语句总结
- 区分DPI、分辨率(PPI)、图像的物理大小、像素宽度
- Linux php 中文乱码解决
- 理解 __declspec(dllexport)和__declspec(dllimport)
- C++ AfxBeginThread
- 新建maven工程时pom.xml报错
- Redis 学习笔记-入门
- position:sticky 定位 position:fixed
- 完全理解 Python 迭代对象、迭代器、生成器(转)
- 网络流24题——数字梯形问题 luogu 4013
- 定位bug的基本要求
- js异步回调
- WHY数学表达式的3D可视化
- transform带来的坑
- 【读书笔记】iOS-自动布局
- php无限分类 下拉框
- 查看sqlserver2008数据库服务器实例名称
- HADOOP与HDFS数据压缩格式