【题解】UVA1252:20の質問

@vjudge
状压
状態は次のように設計できます
dfs(s、a)dfs(s、a)d f s s a 現在推測されているセットを表し、現在ssに明確な数はありませんsセットの共通機能はaaです。a
さらにいくつかの推測。次の推測をkkとして列挙します。
現在の状態の kに対する答えは、
sum = max(dfs(s ∣ 2 k、a)、dfs(s ∣ 2 k、a ∣ 2 k))+ 1 sum = max(dfs(s | 2 ^ k、a)です。 、dfs(s | 2 ^ k、a | 2 ^ k))+ 1S U M=m a x d f s s 2ka d f s s 2ka 2k+1

それぞれのkkk、答えの最小値を取る

境界については、状態(s、a)(s、a)が満たされている場合s 唯一つの番号がである 2以上存在する場合、再度推測;あなたは再び推測する必要はありませんので、より多く存在する場合は、DFSをDFSd f s

コード:

#include <bits/stdc++.h>
#define maxn 2110
using namespace std;
int cnt[maxn][maxn], dp[maxn][maxn], power[25], vis[maxn][maxn], n, m, kase;
char s[maxn];

int dfs(int s, int a){
    
    
	if (cnt[s][a] == 1) return 0;
	if (cnt[s][a] == 2) return 1;
	if (vis[s][a] == kase) return dp[s][a];
	vis[s][a] = kase;
	int ans = m;
	for (int i = 1; i <= m; ++i)
		if (!(s & power[i - 1])){
    
    
			int S = s | power[i - 1], A = a | power[i - 1];
			ans = min(ans, 1 + max(dfs(S, A), dfs(S, a)));
		}
	return dp[s][a] = ans;
}

int main(){
    
    
	power[0] = 1;
	for (int i = 1; i <= 20; ++i) power[i] = power[i - 1] << 1;
	while (1){
    
    
		scanf("%d%d", &m, &n);
		if (m == 0 && n == 0) break;
		++kase;
		for (int i = 0; i < power[m]; ++i)
			for (int j = 0; j < power[m]; ++j) cnt[i][j] = 0;
		for (int i = 1; i <= n; ++i){
    
    
			scanf("%s", s + 1);
			int x = 0;
			for (int j = 1; j <= m; ++j)
				x = (x << 1) | (s[j] == '1');
			for (int j = 0; j < power[m]; ++j) ++cnt[j][j & x];
		}
		printf("%d\n", dfs(0, 0));
	}
	return 0;
}

おすすめ

転載: blog.csdn.net/ModestCoder_/article/details/108563069