• Corn Fields POJ


    第一个题题目链接: POJ - 3254 

    第二个题题目链接:POJ - 1185 

    第一个题的题目大意:给你一个n*m的01矩阵,然后让你安排奶牛,只有为1的地方能安置奶牛,0的地方不能安置奶牛。当在一个为1的地方安置奶牛的时候,这个奶牛的四周都不能防止奶牛,会起冲突。然后问你一共有多少种安置方案。

    具体思路:我们把每一行按照二进制压缩,然后每一次枚举合法的状态,看是否能安置上奶牛,然后枚举当前一行的时候,判断是否冲突就好了。然后最终计算答案的时候累加最后一行为某一个合法状态时的方案数。

    AC代码:

     1 //dp[i][j]代表当前第i行为j时候的合法数。
     2 #include<iostream>
     3 #include<stdio.h>
     4 #include<cmath>
     5 #include<string>
     6 #include<cstring>
     7 #include<algorithm>
     8 using namespace std;
     9 # define ll long long
    10 # define inf 0x3f3f3f3f
    11 const int maxn = 5e3+100;
    12 const int mod  = 1e9;
    13 int dp[20][maxn];
    14 int a[20][20];
    15 int n,m;
    16 bool check(int t1,int t2)
    17 {
    18     if((((t2<<1)&t2)==0)&&(((t2>>1)&t2)==0))
    19     {
    20         for(int j=0; j<m; j++){
    21             if(((t2&(1<<j))&&a[t1][j])||(!(t2&(1<<j))))
    22                 continue;
    23             else
    24                 return false;
    25         }
    26         return true;
    27     }
    28     else
    29         return false;
    30 }
    31 int main()
    32 {
    33     scanf("%d %d",&n,&m);
    34     for(int i=0; i<n; i++)
    35     {
    36         for(int j=0; j<m; j++)
    37         {
    38             scanf("%d",&a[i][j]);
    39         }
    40     }
    41     int maxstate=(1<<m)-1;
    42     for(int i=0; i<n; i++)
    43     {
    44         if(i==0)
    45         {
    46             for(int j=0; j<=maxstate; j++)
    47             {
    48                 if(check(i,j))
    49                     dp[i][j]++;
    50             }
    51         }
    52         else
    53         {
    54             for(int j=0; j<=maxstate; j++)
    55             {
    56                 for(int k=0; k<=maxstate; k++)
    57                 {
    58                     if(check(i,k)&&((j&k)==0))
    59                     {
    60                         dp[i][k]+=dp[i-1][j];
    61                     }
    62                 }
    63             }
    64         }
    65     }
    66 //    for(int i=0;i<=maxstate;i++){
    67 //    cout<<i<<" "<<dp[0][i]<<endl;
    68 //    }
    69     ll sum=0;
    70     for(int i=0; i<=maxstate; i++)
    71     {
    72         sum=(sum+dp[n-1][i])%mod;
    73     }
    74     printf("%lld
    ",sum);
    75     return 0;
    76 }
    View Code

    第二个题题目大意:中文,和上一个题不同的是这个题求的是最大的合法状态。

    具体思路:这个题的难度比上一个题的难度增加了一点,上一个题dp[i][j]表示第i行选j这个状态时的合法数。但是这个题需要判断和上两行的关系。所以我们开一个三维数组。

    dp[i][j][k]代表第i行选择j状态,第i-1行选k这个状态时的合法数。然后求一个最大值就好了。

    具体判断的时候,如果当前的这一行和sto[i],a[i]&sto[j]==sto[j]的时候,就可以了。

    注意需要先预处理出合法的状态,否则会爆内存,因为是个三维空间。

    AC代码:

      1 #include<iostream>
      2 #include<stdio.h>
      3 #include<cmath>
      4 #include<string>
      5 #include<algorithm>
      6 #include<vector>
      7 #include<vector>
      8 using namespace std;
      9 # define ll long long
     10 # define inf 0x3f3f3f3f
     11 const int maxn = 2e2+100;
     12 const int mod  = 1e9;
     13 int dp[100+10][maxn][maxn];
     14 int a[200];
     15 char str[100+100][20];
     16 int sto[maxn],num[maxn];
     17 int n,m;
     18 bool check(int t)
     19 {
     20     if(((t<<1)&t)||((t>>1)&t)||((t<<2)&t)||((t>>2)&t))
     21         return false ;
     22     return true;
     23 }
     24 int cal(int t)
     25 {
     26     int ans=0;
     27     while(t)
     28     {
     29         ans+=(t&1);
     30         t>>=1;
     31     }
     32     return ans;
     33 }
     34 int main()
     35 {
     36     scanf("%d %d",&n,&m);
     37     for(int i=0; i<n; i++)
     38     {
     39         scanf("%s",str[i]);
     40         for(int j=0; j<m; j++)
     41         {
     42             a[i]<<=1;
     43             a[i]|=(str[i][j]=='P'?1:0);
     44         }
     45     }
     46     int cnt=0;
     47     int maxstate=(1<<m)-1;
     48     for(int i=0; i<=maxstate; i++)
     49     {
     50         if(check(i))
     51         {
     52             sto[++cnt]=i;
     53             num[cnt]=cal(i);
     54         }
     55     }
     56     int maxx=0;
     57     for(int i=0; i<n; i++)
     58     {
     59         if(i==0)
     60         {
     61             for(int j=1; j<=cnt; j++)
     62             {
     63                 if((a[i]&sto[j])!=sto[j])continue;
     64                     dp[i][j][0]=max(dp[i][j][0],num[j]);
     65                     maxx=max(maxx,dp[i][j][0]);
     66             }
     67         }
     68         else if(i==1)
     69         {
     70             for(int j=1; j<=cnt; j++)
     71             {
     72                 if((sto[j]&a[i])!=sto[j])continue;
     73                 for(int k=1; k<=cnt; k++)
     74                 {
     75                     if((sto[k]&a[i-1])!=sto[k])continue;
     76                     if((sto[j]&sto[k])!=0)continue;
     77                     dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][0]+num[j]);
     78                     maxx=max(maxx,dp[i][j][k]);
     79                 }
     80             }
     81         }
     82         else
     83         {
     84             for(int j=1; j<=cnt; j++)
     85             {
     86                 if((sto[j]&a[i])!=sto[j])
     87                     continue;
     88                 for(int k=1; k<=cnt; k++)
     89                 {
     90                     if((sto[k]&a[i-1])!=sto[k]||(sto[k]&sto[j])!=0)
     91                         continue;
     92                     for(int L=1; L<=cnt; L++)
     93                     {
     94                         if((sto[L]&a[i-2])!=sto[L])
     95                             continue;
     96                         if((sto[j]&sto[L])!=0||(sto[k]&sto[L])!=0)
     97                             continue;
     98                         dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][L]+num[j]);
     99                         maxx=max(maxx,dp[i][j][k]);
    100                     }
    101                 }
    102             }
    103         }
    104     }
    105     printf("%d
    ",maxx);
    106 }
    View Code
  • 相关阅读:
    解决ipad连接不上电脑的问题
    解决ping 127.0.0.1 一般故障 问题
    DeepLearning.ai学习笔记(五)序列模型 -- week1 循环序列模型
    DeepLearning.ai学习笔记(四)卷积神经网络 -- week4 特殊应用:人力脸识别和神经风格转换
    pip安装 exception记录
    Ubuntu ./configure 半途终止 导致没有生成makefile文件 解决方法
    Open Data Structure Templates
    Win7 下安装VirtualBox 没有Ubuntu 64bit 选项问题
    DataStructure 排序 源码实现
    DS实验题 融合软泥怪-2 Heap实现
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10807760.html
Copyright © 2020-2023  润新知