【题解】UVA1252 Twenty Questions

题意

n 个物品,每个物品有 m 个特征,每次询问一个特征,求最少多少次能确定所求物品。

Solution:

考点:状压 dp 。

首先不能暴力枚举,这样第二个样例输出 5。但是它启发我们当某一组特征 cnt[S]=1 时答案是唯一的。 因为决策是变化的,所以考虑设 dp[S][T] 表示当前问了集合 S 的特征,其中集合 T 的答案是 1 的最小询问数。显然当 cnt[S][T]=1 时返回 0cnt[S][T]=0 是不合法状态。

时间复杂度 O(m3^m+n2^m)

思考:询问顺序是否对答案有影响?

显然是有影响的,因为这个过程不可逆。

输入的时候按十进制输了,导致自闭了一下午。

#include<bits/stdc++.h> #define INF 0x3f3f3f3f #define ll long long using namespace std; int n,m,cnt[1<<11][1<<11],dp[1<<11][1<<11],a[1<<11]; string s; vector<int> vec[15]; map<int,bool> mp; int dfs(int x,int y) { if(cnt[x][y] <= 1) return 0; if(~dp[x][y]) return dp[x][y]; int res = 20; for(int i=0;i<m;i++) { if((x>>i) & 1) continue; res = min(res, max(dfs(x | (1<<i), y), dfs(x | (1<<i), y | (1<<i))) + 1); } return dp[x][y] = res; } int main() { while(scanf("%d%d",&m,&n) && (n || m)) { for(int i=0;i<(1<<m);i++) { for(int j=i;j;j=(j-1)&i) { cnt[i][j] = 0; dp[i][j] = -1; } dp[i][0] = -1; cnt[i][0] = 0; } for(int i=1;i<=n;i++) { cin>>s; a[i]=0; for(int j=0;j<m;j++) { if(s[j] == '1') a[i] |= 1<<j; } for(int j=0;j<(1<<m);j++) { cnt[j][a[i] & j] ++; } } printf("%d\n",dfs(0,0)); } }

__EOF__

本文作者仰望星空的蚂蚁
本文链接https://www.cnblogs.com/cqbzly/p/17530306.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   仰望星空的蚂蚁  阅读(8)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示