UVA1252 【Twenty Questions】
分析
为了叙述方便,设“心里想的物体”为W。首先在读入时把每个物体转化为一个二进制整数。不难发现,同一个特征不需要问两遍,所以可以用一个集合s表示已经询问的特征集。
在这个集合s中,有些特征是W所具备的,剩下的特征是W不具备的。用集合a来表示“已确认物体W具备的特征集”,则a一定是s的子集。
设d(s,a)表示已经问了特征集s,其中已确认W所具备的特征集为a时,还需要询问的最小次数。如果下一次提问的对象是特征k(这就是“决策”),则询问次数为:
max{d(s+{k},a+{k}),d(s+{k}, a)}+1
考虑所有的k,取最小值即可。边界条件为:如果只有一个物体满足“具备集合a中的所有特征,但不具备集合s-a中的所有特征”这一条件,则d(s,a)=0,因为无须进一步询问,已经可以得到答案。
因为a为s的子集,所以状态总数为3m,时间复杂度为O(m3^m)。对于每个s和a,可以先把满足该条件的物体个数统计出来,保存在cnt[s][a],避免状态转移的时候重复计算。统计cnt[s][a]的方法是枚举s和物体,时间复杂度为O(n2^m),所以总时间复杂度为O(n2^m +m3^m)。对于本题的规模来说O(n*2^m)可以忽略不计。
代码实现
#include<bits/stdc++.h>
using namespace std;
template<class T> inline T read(T&x)
{
T data=0;
int w=1;
char ch=getchar();
while(ch!='-'&&!isdigit(ch))
ch=getchar();
if(ch=='-')
w=-1,ch=getchar();
while(isdigit(ch))
data=10*data+ch-'0',ch=getchar();
return x=data*w;
}
const int maxn=150;
int m,n;
int feature[maxn],cnt[(1<<11)+10][(1<<11)+10];
int d[(1<<11)+10][(1<<11)+10];
int dp(int s,int a){
if(d[s][a]!=-1)
return d[s][a];
if(cnt[s][a]<=1)
return d[s][a]=0;
if(cnt[s][a]==2)
return d[s][a]==1;
int ans=20;
for(int i=0;i<m;++i)
if(!(s&(1<<i)))
ans=min(ans, max(dp(s|(1<<i),a),dp(s|(1<<i),a|(1<<i)))+1 );
return d[s][a]=ans;
}
int main()
{
while(read(m)&&read(n))
{
memset(feature,0,sizeof(feature));
char s[20];
for(int i=1;i<=n;++i)
{
scanf("%s",s);
for(int j=0;j<m;++j)
feature[i]|=((s[j]-'0')<<j);
}
/* clog<<"input check"<<endl;
for(int i=1;i<=n;++i)
{
for(int j=0;j<m;++j)
clog<<((feature[i]&(1<<j))?1:0);
clog<<endl;
}
clog<<"input check completed"<<endl;*/
memset(cnt,0,sizeof(cnt));
for(int i=0;i<(1<<m);++i)
for(int j=1;j<=n;++j)
++cnt[i][i&feature[j]];
memset(d,-1,sizeof(d));
printf("%d\n",!dp(0,0)?0:dp(0,0)+1);
}
return 0;
}
另外,输入物体和预处理cnt[s][a]时刘汝佳标程的做法太繁琐,大家可以参考我的做法。
网上有大量AC代码没有预处理,大概比我慢了70ms,而我跑出来是80ms,所以差别不大。有的人可能喜欢不加预处理,这里我也提供一份朴素的代码(不是我打的,有问题别找我)
# include<iostream>
# include<cstdio>
# include<string>
# include<cstring>
# include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
char p[13];
int dp[1<<11][1<<11],sta[130],m,n;
int getVal()
{
int res=0;
for(int i=0;i<m;++i)
if(p[i]=='1')
res|=(1<<i);
return res;
}
int DP(int s,int a)
{
if(dp[s][a]!=INF)
return dp[s][a];
int num=0;
for(int i=0;i<n;++i)///在这里,也可以预处理出来以提高效率;
if((sta[i]&s)==a)///"=="的优先级比"&"的高!!!
++num;
if(num<=1)
return dp[s][a]=0;
int &ans=dp[s][a];
for(int i=0;i<m;++i){
if(s&(1<<i))
continue;
ans=min(ans,max(DP(s|(1<<i),a),DP(s|(1<<i),a|(1<<i)))+1);
}
return ans;
}
int main()
{
while(scanf("%d%d",&m,&n)&&n+m)
{
for(int i=0;i<n;++i){
scanf("%s",p);
sta[i]=getVal();
}
memset(dp,INF,sizeof(dp));
printf("%d\n",DP(0,0));
}
return 0;
}
UVA1252 【Twenty Questions】的更多相关文章
- 【Uva 1252】Twenty Questions
[Link]: [Description] 给你n个物体,每个物体都有m种属性; (每个物体的属性都能和别的物体的属性区别) 现在,你已知这n个物体; 然后让一个人心里想一个物体 你可以问这个人,这个 ...
- Uva1252 Twenty Questions
Twenty Questions https://odzkskevi.qnssl.com/15b7eb4cd1f75f63cee3945b0b845e4f?v=1508411736 [题解] dp[S ...
- 【android studio】android studio使用过程中,搜集的一些问题
1.[知乎]在Android Studio中如何将依赖的jar包放在SDK的android.jar前? 在编译原生Contacts应用时需用到非公开的API,需要引入framework等jar包,但在 ...
- 【netcore基础】.Net core通过 Lucene.Net 和 jieba.NET 处理分词搜索功能
业务要求是对商品标题可以进行模糊搜索 例如用户输入了[我想查询下雅思托福考试],这里我们需要先将这句话分词成[查询][雅思][托福][考试],然后搜索包含相关词汇的商品. 思路如下 首先我们需要把数据 ...
- 【Java基础】反射和注解
前言 在Java中,反射机制和注解机制一直是一个很重要的概念,那么他们其中的原理是怎么样呢,我们不仅仅需要会使用,更要知其然而之所以然. 目录 反射机制 反射如何使用 注解定义 注解机制原理 注解如何 ...
- 【Spring实战】----开篇(包含系列目录链接)
[Spring实战]----开篇(包含系列目录链接) 置顶2016年11月10日 11:12:56 阅读数:3617 终于还是要对Spring进行解剖,接下来Spring实战篇系列会以应用了Sprin ...
- 反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑) C#中缓存的使用 C#操作redis WPF 控件库——可拖动选项卡的TabControl 【Bootstrap系列】详解Bootstrap-table AutoFac event 和delegate的分别 常见的异步方式async 和 await C# Task用法 c#源码的执行过程
反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑) 背景介绍: 为了平衡社区成员的贡献和索取,一起帮引入了帮帮币.当用户积分(帮帮点)达到一定数额之后,就会“掉落”一定数量的“帮帮 ...
- 【python系列】python画报表(Chartkick、Flask)(附中文乱码解决方式)
chartkick 能够画 javascript 报表, 并且比較美观.可是网上搜了下.非常难找到 python 版本号的,于是查了些资料,摸索了下. 对 Flask 也不非常熟悉,这里就仅仅抛砖引玉 ...
- 【33.10%】【codeforces 604C】Alternative Thinking
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
随机推荐
- Style、ControlTemplate 和 DataTemplate 触发器
本文摘要: 1:属性触发器: 2:数据触发器: 3:事件触发器: Style.ControlTemplate 和 DataTemplate 都有触发器集合. 属性触发器只检查W ...
- English trip -- Review Unit5 Around town 在城市
restaurant 餐厅 supermarket 超市 shoping mall 购物中心 drugstore 药店 hospital 医院 laundromat 洗衣店 moive threat ...
- Oracle 11g dataguard check real time apply
2017年8月24日 16:38 环境:oracle 11.2.0.1 OEL-5.8 注:以下操作都在备库执行 总结方法: 1.FPYJ(125_7)@fpyj123> select open ...
- redhat linux 6.2 安装配置GUI
redhat6.2默认不安装GUI,启动时默认进入text模式,下面介绍下安装.配置GUI的步骤: 1.登录root 2.配置及测试yum vi /etc/yum.repos.d/rhel-sou ...
- [LeetCode] 41. First Missing Positive ☆☆☆☆☆(第一个丢失的正数)
Given an unsorted integer array, find the smallest missing positive integer. Example 1: Input: [1,2, ...
- Java中String和byte[]间的 转换浅析
Java语言中字符串类型和字节数组类型相互之间的转换经常发生,网上的分析及代码也比较多,本文将分析总结常规的byte[]和String间的转换以及十六进制String和byte[]间相互转换的原理及实 ...
- css 页面定位position
position的四个属性值 relative absolute fixed static 参看实例 <div id="parent"> <div id='su ...
- 快速切题 sgu117. Counting 分解质因数
117. Counting time limit per test: 0.25 sec. memory limit per test: 4096 KB Find amount of numbers f ...
- [转载]彻底卸载oracleXE数据库服务器
URL:http://www.2cto.com/database/201306/216182.html
- Django(四)模板文件中的循环
编辑views.py from django.shortcuts import render from django.shortcuts import HttpResponse #此行增加 # Cre ...