• [poj2441] Arrange the Bulls


    题意:

    n头公牛,m个仓库,每个公牛有一些自己喜欢的仓库,求每个公牛单独住进仓库的方案数。

    题解:

    状压dp,滚一维,两种写法,实测第一种写法要快些......

    滚掉第一维

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define ll long long
    #define N 21
    #define RG register
    using namespace std;
    
    int dp[1<<N],ve[N][N];
    
    inline int gi() {
      int x=0,o=1; char ch=getchar();
      while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
      if(ch=='-') o=-1,ch=getchar();
      while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
      return o*x;
    }
    
    int main() {
      RG int n=gi(),m=gi(),ans=0;
      for(RG int i=1; i<=n; i++) {
        ve[i][0]=gi();
        for(RG int j=1; j<=ve[i][0]; j++) {
          ve[i][j]=gi();
        }
      }
      dp[0]=1;
      for(RG int i=1; i<=n; i++) {
        for(RG int j=(1<<m)-1; j>=0; j--) {
          if(!dp[j]) continue;//强力剪枝
          for(RG int k=1; k<=ve[i][0]; k++) {
    	if(j&(1<<(ve[i][k]-1))) continue;
    	dp[j|(1<<(ve[i][k]-1))]+=dp[j];
          }
         dp[j]=0;
        }
      }
      for(RG int j=0; j<1<<m; j++) {
        ans+=dp[j];
      }
      printf("%d
    ", ans);
      return 0;
    }
    

    01

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define ll long long
    #define N 21
    #define RG register
    using namespace std;
    
    int dp[2][1<<N],ve[N][N];
    
    inline int gi() {
      int x=0,o=1; char ch=getchar();
      while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
      if(ch=='-') o=-1,ch=getchar();
      while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
      return o*x;
    }
    
    int main() {
      RG int n=gi(),m=gi(),ans=0,now=0;
      for(RG int i=1; i<=n; i++) {
        ve[i][0]=gi();
        for(RG int j=1; j<=ve[i][0]; j++) {
          ve[i][j]=gi();
        }
      }
      dp[now][0]=1;
      for(RG int i=1; i<=n; i++) {
        now^=1;
        for(RG int j=(1<<m)-1; j>=0; j--) {
          if(!dp[now^1][j]) continue;//强力剪枝
          for(RG int k=1; k<=ve[i][0]; k++) {
    	if(j&(1<<(ve[i][k]-1))) continue;
    	dp[now][j|(1<<(ve[i][k]-1))]+=dp[now^1][j];
          }
          dp[now^1][j]=0;
        }
      }
      for(RG int j=0; j<1<<m; j++) {
        ans+=dp[now][j];
      }
      printf("%d
    ", ans);
      return 0;
    }
    
  • 相关阅读:
    LINQ表达式预备讲课
    开发中必须安装的软件
    jquery判断单选按钮radio是否选中的方法
    JQuery判断radio(单选框)是否选中和获取选中值方法总结
    jquery $.each 和for怎么跳出循环终止本次循环
    ECharts 3.0 初学感想及学习中遇到的瓶颈
    js 日期时间大小比较
    Vue资料-简介-旋之华
    vue 引用 vue-resource步骤 (遇错排解)
    vue-resource和axios的简单使用方法总结
  • 原文地址:https://www.cnblogs.com/HLXZZ/p/7687767.html
Copyright © 2020-2023  润新知