【题解】UVA1252 Twenty Questions

该博客讨论了一个关于物品识别的问题,其中涉及到n个物品和m个特征。每个物品有特定的特征组合,通过最少的询问次数来确定某个物品。博主介绍了利用状态压缩动态规划的解决方案,并指出询问顺序对答案的影响。文章中还提到了输入格式错误导致的困扰,以及最终得出的时间复杂度为O(m3^m+n2^m)。
摘要由CSDN通过智能技术生成

题意

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));
	}
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值