zoukankan      html  css  js  c++  java
  • Bus Planning(状压DP)

    前置技能二进制枚举子集

    for(int j=i;j;j=(j-1)&i)

    从集合本身开始

    每次-1,&i保证最后的结果一定是i的子集(0的位置不会变成1)

    及每次都是从左到右消去一个1

    思路:二进制枚举这n个人的子集,判断哪几个状态是能够在一辆车上的,然后对于所有状态判断他的哪两个互补的子集能使得这个状态的人最少。

    //#include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #include<set>
    #include<map>
    #include<vector>
    
    #define inf 0x3f3f3f3f
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ll long long
    #define sd(x) scanf("%d",&(x))
    #define sl(x) scanf("%lld",&(x))
    #define slf(x) scanf("%lf",&(x))
    #define scs(s) scanf("%s",s)
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    #define per(i,a,b) for(int i=a;i>=b;i--)
    #define lowbit(x) x&(-x)
    #define ls now<<1
    #define rs now<<1|1
    #define lson l,mid,ls
    #define rson mid+1,r,rs
    #define All L,R
    
    using namespace std;
    
    const int maxn=3e5+10;
    const int mod=998244353;
    
    map<string ,int>q;
    
    string s[20];
    int nmap[20][20],tot=0;
    int n,m,k,ans=inf,vis[maxn],tans[maxn],dp[maxn],t[35];
    
    int cheek(int mub)
    {
        for(int i=1;i<=mub;i++)
        {
            for(int j=1;j<=mub;j++)
            {
                if(nmap[t[i]][t[j]]) return 0;
            }
        }
        return 1;
    }
    
    void dfs(int u)
    {
        if(dp[u]==1)
        {
            for(int i=0;i<n;i++)
            {
                if(((1<<i))&u)
                    cout<<s[i+1]<<" ";
            }
            cout<<endl;
            return ;
        }
        dfs(u^vis[u]);
        dfs(vis[u]);
    }
    
    int main()
    {
        string a,b;
        sd(n),sd(m),sd(k);
        rep(i,1,n) cin>>s[i],q[s[i]]=i;
        rep(i,1,m) cin>>a>>b,nmap[q[a]][q[b]]=nmap[q[b]][q[a]]=1;
        int N=(1<<n)-1;
        rep(i,0,N)
        {
            int now=i,j=0,mub=0;
            mem(t,0);
            while(now)
            {
                if(now&1) t[++mub]=j+1;
                j++;
                now>>=1;
            }
            dp[i]=inf;
            if(mub>k) continue;
            if(cheek(mub))dp[i]=1;
        }
        for(int i=1;i<=N;i++)
        {
            for(int j=i;j;j=(j-1)&i)
            {
                if(dp[i]>dp[i^j]+dp[j])
                {
                    dp[i]=dp[i^j]+dp[j];
                    vis[i]=j;
                }
            }
        }
        cout<<dp[N]<<endl;
        dfs(N);
        return 0;
    }
  • 相关阅读:
    Grunt构建工具插件篇——之less工具
    Grunt构建工具能做哪些事?
    Grunt-几个常用的任务配置,加载,执行的写法
    单元测试任务包括哪些?
    单元测试的概念
    分享Grunt.js配置: watch + liveReload 实时监测文件变化自动刷新浏览器
    如何使用Grunt(好文)
    grunt安装详解及失败处理
    利用 Grunt (几乎)无痛地做前端开发 (一)之单元测试
    Grunt实现自动化单元测试
  • 原文地址:https://www.cnblogs.com/minun/p/11338000.html
Copyright © 2011-2022 走看看