• 洛谷 P1879 玉米田(状压DP入门题)


    传送门

    https://www.cnblogs.com/violet-acmer/p/9852294.html

    题解:

      相关变量解释:

    1 int M,N;
    2 int plant[maxn][maxn];//草场情况
    3 struct Node
    4 {
    5     int status;//状态
    6     int res;//方案
    7     Node(int a=0,int b=0):status(a),res(b){}
    8 };
    9 vector<Node >dp[maxn];//dp[i][j] : 第i行的j状态能达到的最大方案

      根据dp定义,很容易写出状态转移方程:

     1 for(int i=1;i <= M;++i)
     2 {
     3     for(int j=0;j <= maxNum;++j)
     4     {
     5         int res=Find(j,i-1);//查找与上一次决策没有相邻的草地的决策个数
     6         //isSat1() : 判断草地是否合法,即判断不含有相邻草场
     7         //isSat2() : 判断当前决策是否有相邻的草地
     8         if(isSat1(i,j) && isSat2(j) && res)
     9             dp[i].pb(Node(j,res));
    10     }
    11 }

    AC代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<vector>
     4 using namespace std;
     5 #define R(x) (1<<x)
     6 #define pb(x) push_back(x)
     7 const int MOD=1e8;
     8 const int maxn=12+10;
     9 
    10 int M,N;
    11 int plant[maxn][maxn];//草场情况
    12 struct Node
    13 {
    14     int status;//状态
    15     int res;//方案
    16     Node(int a=0,int b=0):status(a),res(b){}
    17 };
    18 vector<Node >dp[maxn];//dp[i][j] : 第i行的j状态能达到的最大方案
    19 bool isSat1(int i,int x)//判断草地是否合法
    20 {
    21     int index=N;
    22     for(int j=1;j <= N;++j)
    23         if(plant[i][index--] == 0 && (R(j-1)&x) != 0)
    24             return false;
    25     return true;
    26 }
    27 bool isSat2(int x)//判断当前决策是否有相邻的草地
    28 {
    29     for(int j=2;;++j)
    30     {
    31         int val=R(j-1)+R(j-2);
    32         if(val > x)
    33             return true ;
    34         if((val&x) == val)
    35             return false;
    36     }
    37     return true;
    38 }
    39 int Find(int now,int i)//查找与上一次决策没有相邻的草地的决策个数
    40 {
    41     int res=0;
    42     for(int j=0;j < dp[i].size();++j)
    43     {
    44         Node node=dp[i][j];
    45         int pre=node.status;
    46         if((pre&now) == 0)
    47             res=res%MOD+node.res;
    48     }
    49     return res%MOD;
    50 }
    51 void Solve()
    52 {
    53     int maxNum=(1<<N)-1;
    54     dp[0].pb(Node(0,1));
    55     for(int i=1;i <= M;++i)
    56     {
    57         for(int j=0;j <= maxNum;++j)
    58         {
    59             int res=Find(j,i-1);
    60             if(isSat1(i,j) && isSat2(j) && res)
    61                 dp[i].pb(Node(j,res));
    62         }
    63     }
    64     int res=0;
    65     for(int i=0;i < dp[M].size();++i)
    66         res=res%MOD+dp[M][i].res;
    67     printf("%d
    ",res%MOD);
    68 }
    69 int main()
    70 {
    71     scanf("%d%d",&M,&N);
    72     for(int i=1;i <= M;++i)
    73         for(int j=1;j <= N;++j)
    74             scanf("%d",plant[i]+j);
    75     Solve();
    76 }
    View Code
  • 相关阅读:
    MSMQ 跨服务器读写队列的“消息队列系统的访问被拒绝”的解决方案
    WCF中的ServiceHost初始化两种方式
    正则表达式规则
    常用正则表达式
    Visual Studio 2017使用Asp.Net Core构建Angular4应用程序
    斑马打印机ZT410中文打印
    CNPM 安装 for angularjs
    MAC OS X&Vmware
    HBase
    SQL 和 NoSQL 比较
  • 原文地址:https://www.cnblogs.com/violet-acmer/p/9998049.html
Copyright © 2020-2023  润新知