<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      papamelon 321. 鋪磚問題(挑戰程序設計競賽)

      地址 https://www.papamelon.com/problem/321

      解答
      首先是嘗試把該問題轉化成蒙德里安的夢想那道題,但是由于復雜度是2n*2n,當n為15的時候就超時了。
      后面改成了記憶化搜索.可以去掉一些不可能達到的狀態搜索,OK了。
      大概這就是記憶化搜索相對直接遞推DP公式的優勢吧

      int dp[N][M]表示第N行狀態為M的擺放完全的擺放方案數字
      M轉化為01二進制狀態 代表 0為橫放一塊積木。1代表豎放一塊積木.

      兩行沒有沖突的防止方案就是
      1 兩行都是橫放 上行為00 下一行也是00

      2 上一行有豎放 且下一行沒有豎放
      上行為1 下行為0
      也就是 (state1 & state2) ==0

      兩行沒有沖突的合并后 連續的0必須是偶數 否則無法橫放1*2的方塊
      也就是(state1 | state2)的連續0個數必須是偶數

      符合這兩個條件才能說明兩行狀態可以轉化。
      但是這里還有個特例是表示不能放置磚塊的x,
      無論是檢測兩行合并是否可以兼容豎放方塊還是檢測合并后是否有連續的偶數的0 放置,將該位置其當作1 看待

      #include <iostream>
      #include <memory.h>
      
      using namespace std;
      
      const int N = 16;
      const int M = 1 << N;
      
      /*
      3 3 10000
      ...
      .x.
      ...
      */
      
      
      int dp[N][M];
      char mm[N][N];
      int n, m, MOD;
      int st[M];
      int xNum[N];
      
      bool CheckX(int k, int idx) {
      	if ((k & xNum[idx]) != 0) {
      		return false;
      	}
      	return true;
      }
      
      int FillX(int j, int idx) {
      	j |= xNum[idx];
      	return j;
      }
      
      
      //輸入狀態和所在行
      int GetTotal(int state, int line) {
      	int& ret = dp[line][state];
      	if ( ret >= 0) {
      		return ret;
      	}
      
      	ret = 0;
      	int stateFill = FillX(state,line);
      	for (int i = 0; i < 1 << m; i++) {
      		//如果該狀態符合該行的X 并且可以與當前行不沖突
      		//也就是可以從上一行的i狀態轉移過來 加上他的可操作數
      		if ( true == CheckX(i, line - 1) && (stateFill&i) == 0 && 1== st[stateFill | i]) {
      			//if(line -1 == 2)
      				//cout << "line = " << line-1  <<" state = " << i << endl;
      			ret += GetTotal(i,line-1);
      			ret %= MOD;
      		}
      	}
      
      	return ret;
      }
      
      
      void initState() {
      	for (int i = 0; i < 1 << m; i++) {
      		int isvalid = 1; int cnt = 0;
      		for (int j = 0; j < m; j++) {
      			if ((i >> j) & 1) {
      				if (cnt & 1) { isvalid = 0; break; }
      				cnt = 0;
      			}
      			else { cnt++; }
      		}
      		if (cnt & 1) { isvalid = 0; }
      		if (1 == isvalid) { st[i] = 1; }
      	}
      }
      
      //初始化dp數組
      void initDp() {
      	memset(dp, -1, sizeof dp);
      	for (int i = 1; i < M; i++) {
      		dp[0][i] = 0;
      	}
      	dp[0][0] = 1;
      }
      
      void solve() {
      	//初始化dp
      	initDp();
      	//計算所有合乎規則的狀態
      	initState();
      
      	int ans = GetTotal(0,n);
      	cout << ans << endl;
      
      	return;
      }
      
      int main()
      {
      	cin >> n >> m >> MOD;
      	for (int i = 1; i <= n; i++) {
      		for (int j = 0; j < m; j++) {
      			cin >> mm[i][j];
      			if (mm[i][j] == 'x')
      				xNum[i] += 1 << (m - 1 - j);
      		}
      	}
      
      	solve();
      
      	return 0;
      }
      

      我的視頻題解空間

      posted on 2021-12-08 17:38  itdef  閱讀(232)  評論(0)    收藏  舉報

      導航

      主站蜘蛛池模板: 蜜臀98精品国产免费观看| 人妻精品久久无码区| 久久精品噜噜噜成人av| 亚洲av激情一区二区三区| 国产精品无码av不卡| 男人扒女人添高潮视频| 一区二区丝袜美腿视频| 久久精品蜜芽亚洲国产AV| 亚洲码与欧洲码区别入口| 天天做天天爱夜夜爽女人爽| 大兴区| 一区二区三区无码高清视频 | 晋州市| 久久精品国产一区二区三区| 久热伊人精品国产中文| 老司机午夜免费精品视频| 国产午夜福利av在线麻豆| 一二三四中文字幕日韩乱码| 色综合天天综合网国产人| 国产99视频精品免费视频76| 久久人人97超碰国产精品| 体态丰腴的微胖熟女的特征| 亚洲伊人久久精品影院| 国产美女久久久亚洲综合 | 亚洲精品男男一区二区| 精品亚洲欧美高清不卡高清| 国产精品毛片一区二区| 精品无码一区在线观看| 亚洲香蕉免费有线视频| 日本免费视频| 十八禁国产一区二区三区| 日本一卡二卡3卡四卡网站精品| 国产成人午夜福利精品| 一区二区三区放荡人妻| 国产99久久无码精品| 久久久av男人的天堂| 人妻中文字幕av资源站| 色欲天天婬色婬香综合网| 韩国无码AV片午夜福利| 怀远县| 午夜福利电影|