链接:

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3693

题意:

有n(n≤128)个物体,m(m≤11)个特征。每个物体用一个m位01串表示,表示每个特征是具备还是不具备。
我在心里想一个物体(一定是这n个物体之一),由你来猜。
你每次可以询问一个特征,然后我会告诉你:我心里的物体是否具备这个特征。
当你确定答案之后,就把答案告诉我(告知答案不算“询问”)。
如果你采用最优策略,最少需要询问几次能保证猜到?
例如,有两个物体:1100和0110,只要询问特征1或者特征3,就能保证猜到。

分析:

为了叙述方便,设“心里想的物体”为W。首先在读入时把每个物体转化为一个二进制整数。
不难发现,同一个特征不需要问两遍,所以可以用一个集合k表示已经询问的特征集。
在这个集合k中,有些特征是W所具备的,剩下的特征是W不具备的。
用集合c来表示“已确认物体W具备的特征集”,则c一定是k的子集。
设d(k,c)表示已经问了特征集k,其中已确认W所具备的特征集为c时,还需要询问的最小次数。
如果下一次提问的对象是特征i(这就是“决策”),则询问次数为:max{d(k+{i},c+{i}),d(k+{i},c)}+1。
考虑所有的i,取最小值即可。边界条件为:如果只有一个物体满足“具备集合c中的所有特征,
但不具备集合k-c中的所有特征”这一条件,则d(k,c)=0,因为无须进一步询问,已经可以得到答案。
因为c为k的子集,所以状态总数为3^m,时间复杂度为O(m*3^m)。
对于每个k和c,可以先把满足该条件的物体个数统计出来,保存在amt[k][c],避免状态转移的时候重复计算。
统计amt[k][c]的方法是枚举k和物体,时间复杂度为O(n*2^m),对于本题来说可以忽略不计。

代码:

 #include <cstdio>
#include <algorithm>
using namespace std; const int INF = 0x3f3f3f3f;
const int UPM = ;
const int UPN = ;
int n, m, d[<<UPM][<<UPM], amt[<<UPM][<<UPM];
char s[UPN+][UPM+]; void init() {
int u = <<m;
for(int k = ; k < u; k++) {
amt[k][] = ;
d[k][] = INF;
for(int c = k; c; c = k&(c-)) amt[k][c] = , d[k][c] = INF;
}
for(int t = ; t < n; t++) {
int c = ;
for(int i = ; i < m; i++) if(s[t][i] == '') c |= (<<i);
for(int k = ; k < u; k++) amt[k][k&c]++;
}
} int dp(int k, int c) {
int& res = d[k][c];
if(res != INF) return res;
if(amt[k][c] < ) return res = ;
for(int i = ; i < m; i++) {
if(k&(<<i)) continue;
int k2 = k|(<<i), c2 = c|(<<i);
int need = max(dp(k2,c), dp(k2,c2));
res = min(res, need);
}
return res += ;
} int main() {
while(scanf("%d%d", &m, &n) && m) {
for(int i = ; i < n; i++) scanf("%s", s[i]);
init();
printf("%d\n", dp(,));
}
return ;
}

UVa 1252 - Twenty Questions(状压DP)的更多相关文章

  1. UVa 1252 Twenty Questions (状压DP+记忆化搜索)

    题意:有n件物品,每件物品有m个特征,可以对特征进行询问,询问的结果是得知某个物体是否含有该特征,要把所有的物品区分出来(n个物品的特征都互不相同), 最小需要多少次询问? 析:我们假设心中想的那个物 ...

  2. UVA - 1252 Twenty Questions (状压dp+vis数组加速)

    有n个物品,每个物品有m个特征.随机选择一个物品让你去猜,你每次可以询问一个特征的答案,问在采取最优策略时,最坏情况下需要猜的次数是多少. 设siz[S]为满足特征性质集合S的特征的物品总数,dp[S ...

  3. 状压DP+记忆化搜索 UVA 1252 Twenty Questions

    题目传送门 /* 题意:给出一系列的01字符串,问最少要问几个问题(列)能把它们区分出来 状态DP+记忆化搜索:dp[s1][s2]表示问题集合为s1.答案对错集合为s2时,还要问几次才能区分出来 若 ...

  4. UVA - 1252 Twenty Questions (状压dp)

    状压dp,用s表示已经询问过的特征,a表示W具有的特征. 当满足条件的物体只有一个的时候就不用再猜测了.对于满足条件的物体个数可以预处理出来 转移的时候应该枚举询问的k,因为实际上要猜的物品是不确定的 ...

  5. UVa 1204 Fun Game (状压DP)

    题意:有一些小孩(至少两个)围成一圈,有 n 轮游戏,每一轮从某个小孩开始往左或者往右伟手帕,拿到手帕写上自己的性别(B,G),然后以后相同方向给下一个. 然后在某个小孩结束,给出 n 轮手帕上的序列 ...

  6. UVa 11825 Hackers' Crackdown (状压DP)

    题意:给定 n 个计算机的一个关系图,你可以停止每台计算机的一项服务,并且和该计算机相邻的计算机也会终止,问你最多能终止多少服务. 析:这个题意思就是说把 n 台计算机尽可能多的分成一些组,使得每组的 ...

  7. UVa 1252 - Twenty Questions(记忆化搜索,状态压缩dp)

    本文出自   http://blog.csdn.net/shuangde800 题目链接:点击打开链接 题目大意 有n个长度为m的二进制串,每个都是不同的. 为了把所有字符串区分开,你可以询问,每次可 ...

  8. UVA 11825 Hackers’ Crackdown 状压DP枚举子集势

    Hackers’ Crackdown Miracle Corporations has a number of system services running in a distributed com ...

  9. UVA 1412 Fund Management (预处理+状压dp)

    状压dp,每个状态可以表示为一个n元组,且上限为8,可以用一个九进制来表示状态.但是这样做用数组开不下,用map离散会T. 而实际上很多九进制数很多都是用不上的.因此类似uva 1601 Mornin ...

随机推荐

  1. SVN版本控制——SVN 合并的六种方式

    合并的工作是把主干或者分支上合并范围内的所有改动列出,并对比当前工作副本的内容,由合并者手工修改冲突,然后提交到服务器的相应目录里.如果当前工作副本是主干,则合并的范围是分支上的改动,如果工作副本是分 ...

  2. 对象的深度拓展$.extend(true,{},a,b),深入理解,小心陷阱

    转载:https://www.cnblogs.com/DJeanWeb/p/4388689.html $.extend一般情景下,使用深度拓展两个对象时,我们想要的效果是,b对象覆盖掉a对象中存在的所 ...

  3. 面向连接的传输TCP(一)

    这篇博客主要是对计算机网络自顶向上做的阅读笔记,深入地了解TCP 一.TCP连接 1.特点: a.TCP是面向连接的,因为一个进程在向另一个进程进行数据传输之前必须先要握手,即要互相发送报文,以确认信 ...

  4. ZAB 算法

    ZAB (Zookeeper Atomic Broadcast )  zookeeper原子消息广播协议 保证:分布式数据一致性  所有事务请求必须由一个全局唯一的服务器来协调处理,这样的服务器被称为 ...

  5. 虚拟机VMware workstations的网络设置

    一般遇到虚拟机中上不了网的问题,可以这样解决: 1.在终端输入命令:ifconfig.--查看eth0接口上是否有IP地址. 发现eth0接口上没有ip地址. 2.输入cat /etc/sysconf ...

  6. Quiver快速入门

    Quiver快速入门 装载自:https://github.com/HappenApps/Quiver/wiki/Quiver%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8 ...

  7. android之在view中内嵌浏览器的方法

    我要做的一个东西是在一个页面的中间嵌入浏览器,一开始不知道从哪里开始,因为以前用的都是Textveiw或者editVeiw之类的控件,而它们并不能用来显示网页的内容,怎么办呢? 首先想到的是:是不是有 ...

  8. 使用display:none和visibility:hidden隐藏的区别

    今天做毕设时遇到了一个小问题,我做了一个tab导航栏,点击一个tab页其它tab页隐藏,这时候第一想法是使用display:none来控制显示隐藏,写了之后发现使用display会有一个问题,就是第二 ...

  9. sql 日期类型可以使用大于、小于号直接进行比较运算

    select * from emp where hiredate > '1982-1-1';  -- mysqlselect * from emp where hiredate > to_ ...

  10. zookeeper应用 - leader选举 锁

    模拟leader选举: 1.zookeeper服务器上有一个/leader节点 2.在/leader节点下创建短暂顺序节点/leader/lock-xxxxxxx 3.获取/leader的所有子节点并 ...