zoukankan      html  css  js  c++  java
  • 【UVA1252】Twenty Questions

    题面

    有n(n≤128)个物体,m(m≤11)个特征。每个物体用一个m位01串表示,表示每个特征是具备还是不具备。
    我在心里想一个物体(一定是这n个物体之一),由你来猜。
    你每次可以询问一个特征,然后我会告诉你:我心里的物体是否具备这个特征。
    当你确定答案之后,就把答案告诉我(告知答案不算“询问”)。
    如果你采用最优策略,最少需要询问几次能保证猜到?
    例如,有两个物体:1100和0110,只要询问特征1或者特征3,就能保证猜到。

    分析

    dp[k][c]存状态,其中k表示已经询问了的特征,c表示心里所想物体已经确定具备的特征,存的是还需要询问的次数。
    每一次选择一个还没有被确定的特征i,去更新的dp[k|i][c|i]=max(dp[k|i][c|i],dp[k|i][c])+1
    状态太多,用记忆化搜索。边界是这些特征能确定的物品数量,如果<=1,就应该返回了

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define N 12
    #define INF 0x3f3f3f3f
    int n,m,w[N*N],dp[1<<N][1<<N];
    char s[N*N];
    inline void init()
    {
        memset(w,0,sizeof(w));
        memset(dp,0x3f,sizeof(dp));
    }
    
    inline int dfs(int k,int c)
    {
        int &ans=dp[k][c];
        if(ans!=INF)return ans;
        int cnt=0;
        for(int i=1;i<=n;i++)
            if((k&w[i])==c)cnt++;
        if(cnt<=1) {dp[k][c]=0;return 0;}
        for(int i=1;i<=m;i++)
            if((k&(1<<i-1))==0)
                ans=min(ans,max(dfs(k|(1<<i-1),c|(1<<i-1)),dfs(k|(1<<i-1),c))+1);
        return ans;
    }
    
    int main()
    {
        while(scanf("%d%d",&m,&n)&&m)
        {
            init();
            for(int i=1;i<=n;i++)
            {
                scanf("%s",s);
                for(int j=1;j<=m;j++)
                    if(s[j-1]=='1')w[i]|=(1<<j-1);
            }
            printf("%d
    ",dfs(0,0));
        }
        return 0;
    }
    “Make my parents proud,and impress the girl I like.”
  • 相关阅读:
    产品方法论
    elastic search语句
    计算机科学发展的动力
    理论计算机科学学习网站
    算法学习 howto
    人工智能和机器学习 AI&ML howto
    Deep Learning 和 Knowledge Graph howto
    LISP语言学习资源
    Turing Year 2012
    如何做好计算机科学研究
  • 原文地址:https://www.cnblogs.com/NSD-email0820/p/9793195.html
Copyright © 2011-2022 走看看