• UVA


    状压dp,用s表示已经询问过的特征,a表示W具有的特征。

    当满足条件的物体只有一个的时候就不用再猜测了。对于满足条件的物体个数可以预处理出来

    转移的时候应该枚举询问的k,因为实际上要猜的物品是不确定的,要么k是W所具有的,要么k不是W所具有的,

    要保证能猜到那么就应该取最坏情况下的最小值,所以有转移方程:dp[s][a] = min(max(dp[s|1<<k][a],dp[s|1<<k][a|1<<k]))。

    询问特征可能转移到一个非法的状态,即满足条件的物品数量为0个。根据转移方程应该返回0。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxm = 11, maxn = 130;
    
    int cnt[1<<maxm][1<<maxm], m, n, dp[1<<maxm][1<<maxm];
    
    bitset<maxm> obj[maxn];
    const int INF = 0x3fffffff;
    
    void preDeal()
    {
        for(int s = 0,M = 1<<m; s < M; s++){
            fill(cnt[s],cnt[s]+s+1,0);
            fill(dp[s],dp[s]+s+1,INF);
            for(int i = 0; i < n; i++){
                cnt[s][obj[i].to_ulong()&s]++;
            }
        }
    }
    
    int dfs(int s,int a)
    {
        if(cnt[s][a] <= 1) return  0;
        int &ans = dp[s][a];
        if(ans<INF) return ans;
        for(int k = 0; k < m; k++){
            if(s&1<<k) continue;
            int ns = s|1<<k;
            ans = min(ans,max(dfs(ns,a),dfs(ns,a|1<<k))+1);
        }
        return ans;
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(scanf("%d%d
    ",&m,&n),m){
            for(int i = 0; i < n; i++){
                cin>>obj[i];
            }
            preDeal();
            printf("%d
    ",dfs(0,0));
        }
        return 0;
    }
  • 相关阅读:
    c++单例设计模式---17
    c++友元函數---16
    c++const关键字---15
    c++浅拷贝和深拷贝---14
    linux shell 基本语法
    Linux静态库生成
    alsa wav
    Android Butterknife使用方法总结 IOC框架
    利用cglib给javabean动态添加属性,不用在建VO
    钢铁雄心三 通过事件做修改器
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4748841.html
Copyright © 2020-2023  润新知