zoukankan      html  css  js  c++  java
  • POJ-325Corn Fields

    链接:https://vjudge.net/problem/POJ-3254#author=freeloop

    题意:

    农场主John新买了一块长方形的新牧场,这块牧场被划分成M行N列(1 ≤ M ≤ 12; 1 ≤ N ≤ 12),每一格都是一块正方形的土地。John打算在牧场上的某几格里种上美味的草,供他的奶牛们享用。

    遗憾的是,有些土地相当贫瘠,不能用来种草。并且,奶牛们喜欢独占一块草地的感觉,于是John不会选择两块相邻的土地,也就是说,没有哪两块草地有公共边。

    John想知道,如果不考虑草地的总块数,那么,一共有多少种种植方案可供他选择?(当然,把新牧场完全荒废也是一种方案)

    思路:

    状压dp,二进制表示每一行的状态,储存时使用十进制。

    具体思路注释。

    代码:

    #include <iostream>
    #include <memory.h>
    #include <string>
    #include <istream>
    #include <sstream>
    #include <vector>
    #include <stack>
    #include <algorithm>
    #include <map>
    #include <queue>
    #include <math.h>
    #include <cstdio>
    using namespace std;
    
    typedef long long LL;
    const int MAXN = 15;
    const int STATES = 600;
    const int MOD = 1e9;
    
    //377 最多状态
    
    int cur[MAXN];
    int dp[MAXN][STATES];
    int states[STATES];
    int pos = 0;
    
    void Init(int w)
    {
        int total = (1 << w);
        for (int i = 0;i < total;i++)
        {
            if(!(i&(i<<1)))//i往左位移以为,是否有两个1重叠,重叠不满足
                states[++pos] = i;
        }
    }
    
    int main()
    {
        int n, m;
        int flag;
        scanf("%d%d", &m, &n);
        Init(n);
        for (int i = 1;i <= m;i++)
            for (int j = 1;j <= n;j++)
            {
                scanf("%d", &flag);
                if (!flag)//方便判断某种状态是否满足,0时加
                    cur[i] += (1 << (n - j));
            }
    
        for (int i = 1;i <= pos;i++)
        {
            if ((cur[1] & states[i]) == 0)//状态为1表示种,同时行状态为1表示不能种
                dp[1][i] = 1;
        }
    
        for (int i = 2;i <= m;i++)
        {
            for (int j = 1;j <= pos;j++)
            {
                if (states[j] & cur[i])//枚举的状态是否冲突当前行
                    continue;
                for (int k = 1;k <= pos;k++)
                {
                    if (states[k] & cur[i - 1])//枚举的上一行状态是否冲突
                        continue;
                    if (states[j] & states[k])//枚举的上下两行状态是否冲突
                        continue;
                    dp[i][j] = (dp[i][j] + dp[i - 1][k]) % MOD;
                }
            }
        }
    
        int res = 0;
        for (int i = 1;i <= pos;i++)
            res = (res + dp[m][i]) % MOD;
    
        printf("%d
    ", res);
    
        return 0;
    }
    

      

  • 相关阅读:
    html +JS 自学
    Linux下SVN多版本库管理
    Jenkins更换国内源
    Kubernetes Service
    Kubernetes Pod
    ubuntu下vim配置日常工作版本
    PYTHON替代MATLAB在线性代数学习中的应用(使用Python辅助MIT 18.06 Linear Algebra学习)
    mongodb 片键需要思考的问题
    SpringBoot--Easycode插件自定义模板
    Docker-概述
  • 原文地址:https://www.cnblogs.com/YDDDD/p/10359877.html
Copyright © 2011-2022 走看看