zoukankan      html  css  js  c++  java
  • POJ 2441 Arrange the Bulls (状压DP)

    题意:n头牛,m个位置,每头牛有各自喜欢的位置,问安排这n头牛使得每头牛都在各自喜欢的位置有几种安排方法。

    析:dp[i][s] 表示前 i 头牛,已经占的位置是 s,有多少种安排方法,其他的就很简单了,注意用滚动数组  。

    代码如下:

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include <cstdio>
    #include <string>
    #include <cstdlib>
    #include <cmath>
    #include <iostream>
    #include <cstring>
    #include <set>
    #include <queue>
    #include <algorithm>
    #include <vector>
    #include <map>
    #include <cctype>
    #include <cmath>
    #include <stack>
    #include <sstream>
    #define debug() puts("++++");
    #define gcd(a, b) __gcd(a, b)
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define freopenr freopen("in.txt", "r", stdin)
    #define freopenw freopen("out.txt", "w", stdout)
    using namespace std;
    
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef pair<int, int> P;
    const int INF = 0x3f3f3f3f;
    const LL LNF = 1e16;
    const double inf = 0x3f3f3f3f3f3f;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int maxn = 1e6 + 10;
    const int mod = 100000000;
    const int dr[] = {-1, 0, 1, 0};
    const int dc[] = {0, 1, 0, -1};
    const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
    int n, m;
    const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    inline bool is_in(int r, int c){
      return r >= 0 && r < n && c >= 0 && c < m;
    }
    int dp[2][1<<20];
    int a[30][30];
    
    int main(){
      while(scanf("%d %d", &n, &m) == 2){
        for(int i = 1; i <= n; ++i){
          scanf("%d", &a[i][0]);
          for(int j = 1; j <= a[i][0]; ++j){
            scanf("%d", &a[i][j]);
            --a[i][j];
          }
        }
        memset(dp[0], 0, sizeof dp[0]);
        dp[0][0] = 1;
        int cnt = 1;
        int all = 1 << m;
        for(int i = 1; i <= n; ++i, cnt ^= 1){
          memset(dp[cnt], 0, sizeof dp[cnt]);
          for(int j = 0; j < all; ++j){
            if(!dp[cnt^1][j])  continue;
            for(int k = 1; k <= a[i][0]; ++k){
              if(j&(1<<a[i][k]))  continue;
              dp[cnt][j|(1<<a[i][k])] += dp[cnt^1][j];
            }
          }
        }
        int ans = 0;
        for(int i = 0; i < all; ++i)
          ans += dp[cnt^1][i];
        printf("%d
    ", ans);
      }
      return 0;
    }
    

      

  • 相关阅读:
    蓝桥网试题 java 基础练习 特殊的数字
    蓝桥网试题 java 基础练习 杨辉三角形
    蓝桥网试题 java 基础练习 查找整数
    蓝桥网试题 java 基础练习 数列特征
    蓝桥网试题 java 基础练习 字母图形
    蓝桥网试题 java 基础练习 01字串
    蓝桥网试题 java 基础练习 回文数
    蓝桥网试题 java 基础练习 特殊回文数
    Using text search in Web page with Sikuli
    each of which 用法
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/6896238.html
Copyright © 2011-2022 走看看