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;
    }
  • 相关阅读:
    第一课:神经网络与机器学习
    自然语言基础之分词、标注、命名实体识别
    工程能力-语言-框架
    二叉树
    spark入门
    微平台推荐系统介绍(基于java)
    简历项目的梳理和面试准备
    统计学习方法李航学习笔记
    NopCommerce fluent validation使用
    NopCommerce支持多语言
  • 原文地址:https://www.cnblogs.com/minun/p/11338000.html
Copyright © 2011-2022 走看看