250pt: 暴力枚舉所有的可能的情況就好了,求面積的時候我是用梯形的面積減去兩個三角形的面積。。550pt:
題意:給你一個蜂窩形狀的特殊圖形,有一些格子已經被佔據了,問你將剩下的格子用1*2的磚塊儘可能的鋪滿的總方案數,見。
此題想了半天,隱約感覺可以dp,但是無從D起,,,膜拜了下rng_58的超短代碼(大部分人選擇dfs轉移),但是rng_58將圖轉換成網格後巧妙的使用逐格遞推的方法,代碼超短,簡直就是高端洋氣上檔次啊,好想又好寫,這種題我以前都是dfs寫轉移的,要,b半天才能寫出來。。 #include <cstdio>#include <vector>#include <cstring>#include <cstdlib>#include <algorithm>using namespace std;class HexagonalBattlefield{ public :int countArrangements(vector <int> X, vector <int> Y, int N) ;};int g[250][250];long long dp[2][1<<15];const int mod = 2000000011;void Add(long long &x,int y){ x += y; if(x >= mod) x -= mod;}int dx[] = {1,0,-1,0,1,-1};int dy[] = {0,1,0,-1,1,-1};vector<pair<int,int> > p;int HexagonalBattlefield::countArrangements(vector <int> X, vector <int> Y, int N){ N --; for(int i = -N; i <= N; i++) { for(int j = -N; j <= N; j++) if(abs(i-j) <= N ){//ddddd // puts("ddd"); int t = 0; for(int k = 0; k < X.size(); k++) { if(i == X[k] && j == Y[k]) {t=1;break;} } if(!t) p.push_back(make_pair(i,j)); } } // puts("dddd"); int m = p.size(); for(int i = 0; i < m; i++) { int x = p[i].first , y = p[i].second; for(int j = 0; j < 6; j++) { int tx = x + dx[j]; int ty = y + dy[j]; for(int k = 0; k < m; k++) if(tx == p[k].first && ty == p[k].second) { g[i][k] = true; } } } // printf("m=%d\n",m); // puts("debug"); int cur = 0, nxt = 1; dp[cur][0] = 1; for(int i = 0; i < m; i++) { // printf("i=%d\n",i); memset(dp[nxt],0,sizeof(dp[nxt])); for(int j = 0; j < (1<<15); j++) if(dp[cur][j]){ if(j&1) {Add(dp[nxt][j>>1] , dp[cur][j]); continue;} for(int k = 1; k <= 15; k++) if(i+k < m && g[i][i+k] && !( j&(1<<k) ) ) { int mask = ( j | (1 << k) )>> 1; Add(dp[nxt][mask] , dp[cur][j]); } } std::swap(cur,nxt); } return dp[cur][0];}