日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

BZOJ2331: 地板 题解

發(fā)布時間:2024/1/1 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ2331: 地板 题解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

這樣的棋盤地圖容易讓人想到插頭dp
我們可以設計兩種插頭:還沒拐過彎的插頭((#1)和拐過彎的插頭(#2),這樣每個插頭就可以用一個三進制數存儲,為了壓位方便我們用4進制
考慮輪廓線dp時候的轉移,設當前格子的左方插頭為plug1,上方插頭為plug2,有以下幾種轉移(為了方便,這里只討論plug1<=plug2的情況,反過來是一樣的)

  • plug1=0,plug2=0
    有三種轉移:向左邊新建一個#1插頭;向下邊新建一個#1插頭;以這個格子為拐點,向上面和下面同時新建一個#2插頭
  • plug1=0,plug2=1
    有兩種轉移:上面的插頭繼續(xù)向下延伸,即向下的#1插頭,或者在這里拐彎,即向右的#2插頭
  • plug1=0,plug2=2
    有兩種轉移:上面的插頭繼續(xù)向下延伸,即向下的#2插頭,或者在這個格子結束,沒有插頭
  • plug1=1,plug2=1
    只有一種情況:這兩個半截在這個格子會合,當前格子沒有插頭
    很開心,就這么多
    要注意幾個細節(jié):
  • 如果這個格子是障礙物,那么只有plug1=0 && plug2=0的時候才能轉移
  • 轉移的時候要注意“是否能向下/右延伸,即判斷一下是否到了邊界或者有障礙
    行與行之間的轉移是套路轉移
#include <cstdio> #include <iostream> #include <cstring> #include <string> #include <cstdlib> #include <utility> #include <cctype> #include <algorithm> #include <bitset> #include <set> #include <map> #include <vector> #include <queue> #include <deque> #include <stack> #include <cmath> #define LL long long #define LB long double #define x first #define y second #define Pair pair<int,int> #define pb push_back #define pf push_front #define mp make_pair #define LOWBIT(x) x & (-x) using namespace std;const int MOD=20110520; const LL LINF=2e16; const int INF=1e9; const int magic=348; const double eps=1e-10; const int hashmod=4841;inline int getint() {char ch;int res;bool f;while (!isdigit(ch=getchar()) && ch!='-') {}if (ch=='-') f=false,res=0; else f=true,res=ch-'0';while (isdigit(ch=getchar())) res=res*10+ch-'0';return f?res:-res; }int n,m; char a[148][148],tmp[148][148];struct Hash {vector<Pair> hsh[5048];inline void init(){for (register int i=0;i<=hashmod-1;i++)hsh[i].clear();}inline void Insert(int Mask,int newval){int h=Mask%hashmod;newval%=MOD;for (register int i=0;i<int(hsh[h].size());i++)if (hsh[h][i].x==Mask) {hsh[h][i].y+=newval%=MOD;return;}hsh[h].pb(mp(Mask,newval));} }dp[2];//plug=0: no plug //plug=1: a plug before turning //plug=2: a plug after turning inline int getplug(int Mask,int pos) {return (Mask>>((pos-1)<<1))&3;} inline int Set(int Mask,int pos,int newplug) {Mask|=(3<<((pos-1)<<1));Mask^=((3-newplug)<<((pos-1)<<1));return Mask;}int main () {int i,j,x,y,Mask,curval,toMask,toval,plug1,plug2;n=getint();m=getint();for (i=1;i<=n;i++) scanf("%s",a[i]+1);if (n<m){swap(n,m);for (i=1;i<=n;i++)for (j=1;j<=m;j++)tmp[i][j]=a[m-j+1][i];for (i=1;i<=n;i++)for (j=1;j<=m;j++)a[i][j]=tmp[i][j];}dp[0].init();dp[1].init();dp[0].Insert(0,1);int cur=1,pre=0;for (x=1;x<=n;x++){for (y=1;y<=m;y++){dp[cur].init();for (i=0;i<=hashmod-1;i++)for (j=0;j<int(dp[pre].hsh[i].size());j++){Mask=dp[pre].hsh[i][j].x;curval=dp[pre].hsh[i][j].y;plug1=getplug(Mask,y);plug2=getplug(Mask,y+1);if (a[x][y]=='*'){if (!plug1 && !plug2) dp[cur].Insert(Mask,curval);}else{if (!plug1 && !plug2){if (x!=n && a[x+1][y]=='_' && y!=m && a[x][y+1]=='_') toMask=Set(Set(Mask,y,2),y+1,2),dp[cur].Insert(toMask,curval);if (x!=n && a[x+1][y]=='_') toMask=Set(Mask,y,1),dp[cur].Insert(toMask,curval);if (y!=m && a[x][y+1]=='_') toMask=Set(Mask,y+1,1),dp[cur].Insert(toMask,curval);}if (plug1==1 && !plug2){if (y!=m && a[x][y+1]=='_') toMask=Set(Set(Mask,y,0),y+1,1),dp[cur].Insert(toMask,curval);if (x!=n && a[x+1][y]=='_') toMask=Set(Mask,y,2),dp[cur].Insert(toMask,curval);}if (plug1==2 && !plug2){if (y!=m && a[x][y+1]=='_') toMask=Set(Set(Mask,y,0),y+1,2),dp[cur].Insert(toMask,curval);toMask=Set(Mask,y,0);dp[cur].Insert(toMask,curval);}if (!plug1 && plug2==1){if (x!=n && a[x+1][y]=='_') toMask=Set(Set(Mask,y,1),y+1,0),dp[cur].Insert(toMask,curval);if (y!=m && a[x][y+1]=='_') toMask=Set(Mask,y+1,2),dp[cur].Insert(toMask,curval);}if (plug1==1 && plug2==1){toMask=Set(Set(Mask,y,0),y+1,0);dp[cur].Insert(toMask,curval);}if (!plug1 && plug2==2){if (x!=n && a[x+1][y]=='_') toMask=Set(Set(Mask,y,2),y+1,0),dp[cur].Insert(toMask,curval);toMask=Set(Mask,y+1,0);dp[cur].Insert(toMask,curval);}}}swap(cur,pre);}if (i==n) continue;dp[cur].init();for (i=0;i<hashmod;i++)for (j=0;j<int(dp[pre].hsh[i].size());j++){Mask=dp[pre].hsh[i][j].x;curval=dp[pre].hsh[i][j].y;dp[cur].Insert(Mask<<2,curval);}swap(cur,pre);}for (i=0;i<int(dp[pre].hsh[0].size());i++)if (dp[pre].hsh[0][i].x==0) {printf("%d\n",dp[pre].hsh[0][i].y);return 0;}printf("0\n");return 0; }

總結

以上是生活随笔為你收集整理的BZOJ2331: 地板 题解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。