Twenty Questions UVA - 1252

题目传送门

思路:这个题目很巧妙啊,一看就是一个状压DP,但是这个题我觉得难点在于如何求得状态转移以后的状态,一开始想了很久都没有想出来,然后看了lrj的书上写的,确实十分的巧妙,我们用dp[s][a]来表示当前已经询问了集合s的问题,具有集合a特征的还要询问最少多少次才能求得最优解,然后我们可以预处理一个数组来记录每一个状态下有多少个满足的物体。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define MAXN 150
#define MAXE 11
#define MAX_SIZE 8
#define INF 0x3fffffff
#define EPS 1e-6
#define MOD 1000000007
#define LL long long
#define ULL unsigned long long
#define pi 3.14159

using namespace std;

int n, m;
int arr[MAXN];
int dp[(1 << MAXE) + 10][(1 << MAXE) + 10];
int num[(1 << MAXE) + 10][(1 << MAXE) + 10];

int change(const string &str) {
    int ans = 0;
    for (int i = 0; i < str.length(); ++i) {
        ans = ans * 2 + str[i] - '0';
    }
    return ans;
}

void init() {
    memset(num, 0, sizeof(num));
    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j < (1 << m); ++j) {
            num[j][j & arr[i]]++;
        }
    }
    memset(dp, -1, sizeof(dp));
}

int DFS(int s, int a) {
    int &ans = dp[s][a];
    if (ans > -1) {
        return ans;
    }
    if (num[s][a] == 1) {
        return ans = 0;
    } else if (num[s][a] == 2) {
        return ans = 1;
    }
    ans = m;
    for (int i = 0; i < m; ++i) {
        if (!(s & (1 << i)) && num[s | (1 << i)][a | (1 << i)] && num[s | (1 << i)][a]) {
            int temp = max(DFS(s | (1 << i), a), DFS(s | (1 << i), a | (1 << i))) + 1;
            ans = min(ans, temp);
        }
    }
    return ans;
}

int main() {
    std::ios::sync_with_stdio(false);
    while (cin >> m >> n) {
        if (n == 0 && m == 0) {
            break;
        }
        string str;
        for (int i = 1; i <= n; ++i) {
            cin >> str;
            arr[i] = change(str);
        }
        init();
        cout << DFS(0, 0) << endl;
    }
    return 0;
}

/*
 8 1
 11010101
 11 4
 00111001100
 01001101011
 01010000011
 01100110001
 11 16
 01000101111
 01011000000
 01011111001
 01101101001
 01110010111
 01110100111
 10000001010
 10010001000
 10010110100
 10100010100
 10101010110
 10110100010
 11001010011
 11011001001
 11111000111
 11111011101
 11 12
 10000000000
 01000000000
 00100000000
 00010000000
 00001000000
 00000100000
 00000010000
 00000001000
 00000000100
 00000000010
 00000000001
 00000000000
 9 32
 001000000
 000100000
 000010000
 000001000
 000000100
 000000010
 000000001
 000000000
 011000000
 010100000
 010010000
 010001000
 010000100
 010000010
 010000001
 010000000
 101000000
 100100000
 100010000
 100001000
 100000100
 100000010
 100000001
 100000000
 111000000
 110100000
 110010000
 110001000
 110000100
 110000010
 110000001
 110000000
 0 0
 */

你可能感兴趣的:(UVA,状压DP)