您的位置:首页 > 其它

POJ 2411 Mondriaan's Dream 轮廓线动态规划,插头dp,滚动数组

2017-09-16 21:15 375 查看
原题链接

设矩阵共m列,n行,设当前状态为k

d[i][j][k]:当前格子坐标为(i,j),之前的连续m个格子的状态为k

状态转移:

①若k最高位为1,可以不放

②若k最高位为0,可以朝上竖着放

③若k最高位为1,可以向朝左横着放

注:

①初始状态说明:

d[(1<<m)-1]=1 (*)

当首次循环,i=j=0,设第0行之前有一虚拟行,则初始状态即(设m=4):

(当前格子用p表示)

1 1 1 1

p         (第0行)

则此状态唯一可行的决策是不放,故有:d[0][0][1110]=d[初始状态][1111]=1

则第二次循环,即i=0,j=1,则对于满足如下状态:

   1 k1 k2

0 p         (第0行)

的所有状态k有唯一决策(设新状态为k'):横放,即d[0][1][k']=sigma(d[0][0][k] | k为满足以上状态的所有状态)

已知,对于一行两列的矩阵,合法摆放应该只有一种,所以d[0][1][k']=1,又仅当k为1110时才有值1,其它满足条件的k的d值均为0,所以若按此(*式)设置初始状态,则正好满足条件。而对于1行1列的特殊状态,即d[0][0][1111],仍为0,也符合事实。这是初始状态设置的原因。

②对于已经确定当前k的最高位为1的状态(转移1、3),那么k<<1的最高位也为1,所以清除新的溢出位(第m+1位)k应使用异或:(k<<1)^(1<<m)。

③本题使用滚动数组减少空间占用,详见滚动数组说明:滚动数组的应用

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int k,n,m,cur;
long long d[2][1<<15];
void update(int a,int b){d[cur][b]+=d[1-cur][a];}
///a:former k, b:current k, k'
///d[i][j][s]: the maximum setting plans when at cell(i,j),
///and the state of m continuous cells ended with cell(i,j) is s
int main(){
while(scanf("%d%d",&n,&m)){
if(m==0&&n==0) break;
if(n<m) swap(n,m);
memset(d,0,sizeof(d));
cur=0;
d[0][(1<<m)-1]=1;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
cur^=1;
memset(d[cur],0,sizeof(d[cur]));
for(int k=0;k<(1<<m);k++){
///assume former k->k, current k->k'
if(k&(1<<(m-1))) update(k,(k<<1)^(1<<m));///not set
///condition: the highest bit(m th, count from 1) of k is 1,
if(i&&!(k&(1<<(m-1)))) update(k,(k<<1)^1);///set upward
///condition: the highest bit (m th) of k is 0, and i>0
if(j&&!(k&1)&&(k&(1<<(m-1)))) update(k,(k<<1)^3^(1<<m));///set leftward
///condition: the highest bit (m th) of k is 1, the lowest bit of k is 0
}
///in every repeating, the highest bit of former k will be filled with 1, so in the end,
///every cell in the first (n-1) rows will be filled with 1, so if the last row(n th) is filled with 1 ((1<<m)-1),
///current state will be the answer
}
printf("%lld\n",d[cur][(1<<m)-1]);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm poj dp