On top of the basement of size 1*1*w, we like to construct a building object using three types of bricks, whose sizes are 1*1*1, 1*1*2, 1*1*3, respectively. The height of the building is at most h. How many different type of buildings could you construct under some constraints? -- A concise summery is like that.
At first glance, I was like, "Umm, this is a simple bit DP problem." But it took me longer to implement the idea than I thought. Guess I have to solve this level of problem within 30 minutes to be a yellow coder. Just need more practices!!
- const LL MOD = 1000000007LL;
- LL dp[10+1][1<<10];
- LL ptr[1<<10][1<<10];
- void init(int x, int y, int b) {
- if ((1<<b) > x) return;
- init(x, y, b+1);
- if (x >> b & 1) {
- init(x, y | 1<<b, b+1);
- ++ptr[x][y | 1<<b] %= MOD;
- }
- if ((x >> b & 1) && (x >> (b+1) & 1)) {
- init(x, y | 3<<b, b+2);
- ++ptr[x][y | 3<<b] %= MOD;
- }
- if ((x >> b & 1) && (x >> (b+2) & 1)) {
- init(x, y | 7<<b, b+3);
- ++ptr[x][y | 7<<b] %= MOD;
- }
- }
- class SmallBricks31 {
- public:
- int countWays(int w, int h) {
- memset(dp, 0, sizeof(dp));
- memset(ptr, 0, sizeof(ptr));
- REP(i, 1<<10) {
- if (i > 0) {
- int b = 0;
- while (!(i & 1<<b))
- ++b;
- init(i, 0, b);
- }
- }
- dp[0][(1<<w)-1] = 1;
- REP(i, h) REP(j, 1<<w) {
- if (!dp[i][j]) continue;
- REP(k, 1<<w) {
- if (ptr[j][k]) {
- LL tmp = dp[i][j] * ptr[j][k] % MOD;
- dp[i+1][k] = (dp[i+1][k] + tmp) % MOD;
- }
- }
- }
- LL ret = 0;
- FOR (i, 1, h+1) REP(j, 1<<w) ret = (ret + dp[i][j]) % MOD;
- return ++ret % MOD;
- }
- };
0 件のコメント:
コメントを投稿