zoukankan      html  css  js  c++  java
  • UVa 1252 (状压DP + 记忆化搜索) Twenty Questions

    题意:

    有n个长为m的各不相同的二进制数(允许存在前导0),别人已经事先想好n个数中的一个数W,你要猜出这个数。

    每次只可以询问该数的第K为是否为1.

    问采用最优询问策略,则最少需要询问多少次能保证猜到。

    比如有1100 和 0110两个数,只需要询问第一或第三位数是否为1,即可猜中,因此答案为1.

    分析:

    d(s, a)表示已经询问了的集合s,在已经询问了的集合中W中为1的集合为a,还需要询问多少次。

    如果下一次询问第k位,则询问次数为:

      

    然后取所有k里的最小值即可。

    预处理:

    对于每个s和a,可以先把满足条件的数的个数记录下来,保存在cnt[s][a]里。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 using namespace std;
     5 
     6 const int maxm = 12, maxn = 130;
     7 char object[maxn][maxm + 10];
     8 int d[1<<maxm][1<<maxm], cnt[1<<maxm][1<<maxm], vis[1<<maxm][1<<maxm];
     9 int m, n, kase = 0;
    10 
    11 int dp(int s, int a)
    12 {
    13     if(cnt[s][a] <= 1)  return 0;
    14     if(cnt[s][a] == 2)  return 1;
    15 
    16     int& ans = d[s][a];
    17     if(vis[s][a] == kase)  return ans;
    18     vis[s][a] = kase;
    19 
    20     ans = m;
    21     for(int k = 0; k < m; ++k)
    22     {
    23         if(!(s&(1<<k)))
    24         {
    25             int s2 = s | (1<<k), a2 = a | (1<<k);
    26             if(cnt[s2][a] >= 1 && cnt[s2][a2] >= 1)
    27             {
    28                 int need = max(dp(s2, a2), dp(s2, a)) + 1;
    29                 ans = min(ans, need);
    30             }
    31         }
    32     }
    33     return ans;
    34 }
    35 
    36 int main()
    37 {
    38     //freopen("in.txt", "r", stdin);
    39     while(scanf("%d%d", &m, &n) && n)
    40     {
    41         ++kase;
    42         for(int i = 0; i < n; ++i)
    43             scanf("%s", object[i]);
    44         memset(vis, 0, sizeof(vis));
    45         memset(cnt, 0, sizeof(cnt));
    46         for(int i = 0; i < n; ++i)
    47         {
    48             int feature = 0;
    49             for(int f = 0; f < m; ++f)
    50                 if(object[i][f] == '1') feature |= (1 << f);
    51             for(int s = 0; s < (1<<m); ++s)
    52                 cnt[s][s&feature]++;
    53         }
    54         printf("%d
    ", dp(0, 0));
    55     }
    56 
    57     return 0;
    58 }
    代码君
  • 相关阅读:
    [hdu7034]Array
    [hdu7012]Miserable Faith
    CF 1559D2. Mocha and Diana
    CF 1447E Xor Tree
    2021年-华为杯-物联网大赛(1)
    去掉e-select下拉框的小三角图案
    element中使用select组件 下拉框位置偏移的解决方法
    SQL注入之高权限注入
    SQL注入基础简介
    增删改查的实现
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4068756.html
Copyright © 2011-2022 走看看