1. 程式人生 > 實用技巧 >NOI前做題紀錄

NOI前做題紀錄

  快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