您的位置:首页 > 其它

POJ 2411 Mondriaan's Dream

2014-01-18 18:14 162 查看
基本思想是基于状态压缩的动态规划。

按照每一行顺序放置,由于方块的形状限制,每一行的放置情形只跟上一行有关,而跟这之前的无关,这就为采用动态规划算法提供了依据。

可分三种情况来单独讨论:

①当前位置不放置方块。则上一行的相应位置必须填充方块,否则以后都不可能填充。

②当前位置竖放方块。上一行相应位置必须为空,否则就会产生方块的重叠。

③当前位置横放方块。上一行相应位置必须填充方块

第一行比较特殊,它的上一行可以认为是已经填满的,需要单独来计算。

整个算法可以结合递归来实现。

#include <vector>
#include <list>
#include <limits.h>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string.h>
#include <stdlib.h>
using namespace std;

int row, col;
long long dp[12][1<<12];
void dfs_fir(int c, int state);
void dfs(int r, int c, int cur, int pre);
int main(){
while(cin>>row>>col){
if(row==0 && col==0) break;
memset(dp, 0, sizeof(dp));
dfs_fir(0, 0);
for(int i=1; i<row; i++)
dfs(i, 0, 0, 0);
cout<<dp[row-1][(1<<col)-1]<<endl;
}// end while loop
return 0;
}

void dfs_fir(int c, int state){
if(c > col) return;
if(c==col){
++dp[0][state];
return;
}
dfs_fir(c+1, state<<1);
dfs_fir(c+2, (state<<2)|3);
return;
}// end method dfs_fir

void dfs(int r, int c, int cur, int pre){
if(c > col) return;
if(c == col){
dp[r][cur] += dp[r-1][pre];
return;
}
// place vertically
dfs(r, c+1, (cur<<1)|1, pre<<1);
// place horizontally
dfs(r, c+2, (cur<<2)|3, (pre<<2)|3);
// not place
dfs(r, c+1, cur<<1, (pre<<1)|1);
return;
}// end method dfs
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: