快NOI了还啥都不会,蛤蛤要梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒梅勒。

  为什么我的键盘还不到还不到还不到还不到还不到还不到还不到还不到。

  不一定每道题都写,不一定写的很清楚,各位无聊的时候可以看着玩玩,咕咕咕。

 

白金元首与莫斯科

  比较巧妙的题目,顺着倒着分别轮廓线dp,在障碍处拼起来。因为空格子可能非常麻烦,所以将其视为1*1的小方格,这样就只有目前考虑的轮廓线可能有空了。当两个轮廓拼起来时,所有空格就必须填上,所以轮廓线必须相应对上,才能用竖直方格填满。

  
  1 # include <cstdio>
  2 # include <iostream>
  3 # define R register int
  4 
  5 using namespace std;
  6 
  7 const int N=20;
  8 const int Q=(1<<17)+100;
  9 const int mod=1000000007;
 10 int n,m,q,a[N][N],bit[N];
 11 int f[N][N][Q],g[N][N][Q];
 12 
 13 void add (int &a,int b)
 14 {
 15     a+=b;
 16     if(a>=mod) a-=mod;
 17 }
 18 
 19 int ask (int i,int j)
 20 {
 21     int ans=0;
 22     for (R k=0;k<=q;++k)
 23         if(k&bit[j])
 24         add(ans,1LL*f[i][j-1][k]*g[i][j+1][k]%mod);
 25     return ans;
 26 }
 27 
 28 int main()
 29 {
 30     scanf("%d%d",&n,&m);
 31     for (R i=1;i<=m;++i) bit[i]=1<<(i-1);
 32     for (R i=1;i<=n;++i)
 33         for (R j=1;j<=m;++j)
 34             scanf("%d",&a[i][j]);
 35     q=(1<<m)-1;
 36     f[1][0][q]=1;
 37     for (R i=1;i<=n;++i)
 38         for (R j=1;j<=m;++j)
 39         {
 40             for (R k=0;k<=q;++k)
 41             {
 42                 int t=f[i][j-1][k];
 43                 if(t==0) continue;
 44                 if((k&bit[j])==0)
 45                 {
 46                     if(a[i][j]) continue; //上面那个一定不能空,否则永远填不上
 47                     add(f[i][j][ k|bit[j] ],t);
 48                     continue;
 49                 }
 50                 if(a[i][j]) add(f[i][j][k],t);
 51                 else
 52                 {
 53                     add(f[i][j][k],t);
 54                     add(f[i][j][k^bit[j]],t);
 55                     if(j!=1&&(k&bit[j-1])==0) add(f[i][j][ k|bit[j-1] ],t);
 56                 }
 57             }
 58             if(j==m)
 59             {
 60                 for (R k=0;k<=q;++k) 
 61                     f[i+1][0][k]=f[i][j][k];
 62             }
 63         }
 64     g[n][m+1][q]=1;
 65     for (R i=n;i>=1;--i)
 66         for (R j=m;j>=1;--j)
 67         {
 68             for (R k=0;k<=q;++k)
 69             {
 70                 int t=g[i][j+1][k];
 71                 if(!t) continue;
 72                 if((k&bit[j])==0)
 73                 {
 74                     if(a[i][j]) continue;
 75                     add(g[i][j][ k|bit[j] ],t);
 76                     continue;
 77                 }
 78                 if(a[i][j]) add(g[i][j][k],t);
 79                 else
 80                 {
 81                     add(g[i][j][k],t);
 82                     add(g[i][j][k^bit[j]],t);   
 83                     if(j!=m&&(k&bit[j+1])==0)
 84                         add(g[i][j][k|bit[j+1]],t);
 85                 }
 86             }
 87             if(j==1)
 88             {
 89                 for (R k=0;k<=q;++k)
 90                     g[i-1][m+1][k]=g[i][j][k];
 91             }
 92         }
 93     for (R i=1;i<=n;++i)
 94     {
 95         for (R j=1;j<=m;++j)
 96         {
 97             if(a[i][j]) printf("0 ");
 98             else printf("%d ",ask(i,j));
 99         }
100         printf("\n");
101     }
102     return 0;
103 }
code

相关文章:

  • 2022-01-11
  • 2021-08-12
  • 2021-06-30
  • 2021-06-04
  • 2021-05-25
  • 2021-12-30
  • 2021-10-30
  • 2021-08-18
猜你喜欢
  • 2021-05-27
  • 2022-12-23
  • 2021-09-02
  • 2021-05-27
  • 2021-08-15
  • 2021-08-05
  • 2022-03-01
相关资源
相似解决方案