zoukankan      html  css  js  c++  java
  • Twenty Questions UVA

    题目大意:

    有n个01串,长度为m。可以询问某一位,将串相互区别。问在最优方案下,至多要问几次,才能将某一个串区别出来

    举个例子:

    1000

    0011

    0010

    1011

    区别出第一个串,只需要问第一位;

    区别出第二个串或第三个串,只需要问后两位;

    区别出第四个串,也只需要问两位

    因此答案是2

    思路:

    考虑一个询问序列,如果能区别出一个串出来,就是合法的

    可光有询问序列不好办啊,要有具体的询问结果啊,那就表示出来呗

    对每个询问,就要考虑不同的结果,就好了

    就能dp了,状态f(s,s0),分别表示出询问序列,和结果为1的位

    s0是s的子集

    就有f[s][s0]=min(f[s][s0],1+max( f(s^t,s0) , f(s^t,s0^t) )),t为新考虑的一位

    结果就是f(0,0)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    
    const int OM=1<<11,N=128+3;
    const int INF=0x7f7f7f7f;
    
    #define ll long long 
    
    int m,n,all;
    ll a[N];
    int dp[OM][OM];
    
    bool belong(int a,int b)
    {
        return (a&b)==a;
    }
    bool judge(int s,int s0)
    {
        int cnt=0;
        for(int i=1;i<=n;i++)
            //if((s&a[i])==s0)
            if( belong(s0,a[i])&& belong( s^s0,~a[i] ) )
                cnt++;
        return cnt<=1;
    }
    int dps(int s,int s0)
    {
        if(dp[s][s0]!=-1)
            return dp[s][s0];
            
        if(judge(s,s0))
            return dp[s][s0]=0;
            
        dp[s][s0]=INF;
        
        for(int t=1 ; t<all ; t<<=1)
            if(!(s&t))
                dp[s][s0]=min(dp[s][s0],1+max( dps(s^t,s0) , dps(s^t,s0^t) ));
        return dp[s][s0];
    }
    int binar(ll x)
    {
        int ret=0;
        for(int i=1;i<=m;i++)
        {
            ret<<=1;
            if(x%10)ret^=1;
            x/=10;
        }
        return ret;
    }
    int main()
    {
        while(scanf("%d%d",&m,&n)==2 && m+n)
        {
            all=1<<m;
            for(int i=1;i<=n;i++)
            {
                scanf("%lld",&a[i]);
                a[i]=binar(a[i]);
            }
            memset(dp,0xff,sizeof(dp));
            printf("%d
    ",dps(0,0));
        }    
        return 0;
    }
  • 相关阅读:
    常用python机器学习库总结
    链接器link.exe 编译器cl.exe 资源编译器rc.exe
    LRESULT与wParam和lParam的问题
    CreateDialog和DialogBox
    如何通俗易懂地解释卷积?
    深度学习在graph上的使用
    一文弄懂神经网络中的反向传播法——BackPropagation
    WM_COMMAND消息
    win32编程中消息循环和WndProc()窗口过程函数
    使用UEditor 的时候,ajax注意使用同步的方法
  • 原文地址:https://www.cnblogs.com/mgnfcnt/p/8150476.html
Copyright © 2011-2022 走看看