之前断断续续地在轮廓线dp上花了一些时间,尝试秒懂。但是失败了。。今晚花了一下时间,总算初步入门了。
首先根据白书上的解释,轮廓线动归首先要求在一个较窄的棋盘状空间上。
(1)窄,可以理解,状压总不能压爆内存嘛。
(2)棋盘状这个特点,决定了dp从左上到右下的合理性。
忽然想到学这个是因为Poi上有道题被卡住了。。结果翻来翻去翻了翻CDQ论文&PPT
毕竟看ppt讲解然后秒懂都是神犇。理所当然:还是没懂,不明觉厉。
1h过去了。。被自己蠢死了。。
于是去看blog,果然好懂多了。
pistures below are not mine!
----------------------------------------------------------------------------------------------------------------------------------
从入门的题目做起:
hdu1693!入门题oh yeah!
分析题目不难发现要求是所有非障碍格都要有两个插头,左右障碍格没有插头
于是分析开始(举例说明):
插头状态{1,0,1,1,1,1} 凹角有两个插头,为了让当前的决策格有且只有两个插头,不加插头。
插头状态{1,0,0,1,1,1} 凹角有一个插头,为了让当前的决策格有且只有两个插头,可有两种选择:右插头或下插头。
插头状态{1,0,0,0,1,1} 凹角有没有插头,为了让当前的决策格有且只有两个插头,必须加右插头和下差头。
至于障碍格,如果没有插头,合法转移,如果有插头,不合法置为0。
有了以上分析,状态也就不难想了:f[i][j][opt],(i,j)为决策格位置,opt为插头的状态。
状态的转移,这道题就按照以上分析的标准转移,但不同的题各不相同。。虽然我自己也还没做。
可以由凸角插头的方案倒推凹角插头方案数,也可以用凹角插头方案数正推凸角插头方案数,看个人思维方式了。
不管正推逆推,答案都是f[n][m][0]。
-------------------------------------------------------------------------------------------------------------------------------------------------------
hdu1693:
Code:
#include<iostream>
#include<cstdio>
#include<cstring>
#define For(i,l,r) for(int (i)=(l);(i)<=(r);(i)++)
using namespace std;
typedef long long ll;
const int N=13;
ll f[N][N][1<<N],m,n;
int map[N][N];
void dp(){
memset(f,0,sizeof(f));
f[0][m][0]=1;
For(i,1,n){
For(j,0,(1<<m)-1) f[i][0][j<<1]=f[i-1][m][j];
For(j,1,m) For(opt,0,(1<<(m+1))-1){
int x=1<<j,y=1<<(j-1);
if(map[i][j]){
if((opt&x)!=0&&(opt&y)!=0) f[i][j][opt]=f[i][j-1][opt-x-y];//凹角有两个插头 凸角不能再有插头
else if((opt&x)==0&&(opt&y)==0) f[i][j][opt]=f[i][j-1][opt+x+y]; //凹角没有插头 凸角必须有两个插头
else f[i][j][opt]=f[i][j-1][opt^x^y]+f[i][j-1][opt]; //凹角一个插头 凸角插头可右可下
}else{
if((opt&x)==0&&(opt&y)==0) f[i][j][opt]=f[i][j-1][opt]; //障碍处没有插头 直接转移
else f[i][j][opt]=0; //障碍处出现插头 非法
}
}
}printf("There are %I64d ways to eat the trees.\n",f[n][m][0]);
//当前格为(n,m),且轮廓线上不存在任何插头的情况方案数,就是答案
}
int main(){
freopen("1693.in","r",stdin);
int T,cnt=0;
scanf("%d",&T);
while(T--){
cnt++;
scanf("%d%d",&n,&m);
For(i,1,n) For(j,1,m)
scanf("%d",&map[i][j]);
printf("Case %d: ",cnt);
dp();
}
return 0;
}