您的位置:首页 > 其它

POJ 1038 Bugs Integrated, Inc. (状态dp)

2012-07-30 15:20 330 查看
确实是好题。。。看解题报告看了一天半,才大概明白是怎么样一个过程。最让我纠结的是M,N的行列问题。。。。文字描述里的M,N和图片上的M,N不对应。本菜只能无比蛋疼而又晕晕乎乎的看。。。

-------------------------------以下部分转自大牛chinaeli-----------------------------------------http://hi.baidu.com/chinaeli/blog/item/b932d4b430d60ac636d3ca34.html

好了,废话说道这里,我来说说我的想法(其实这个方法都是大家用的,我也是效仿别人的方法)
首先说一下如何用三进制表示状态:

View Code

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define Max(a,b) (a>b?a:b)
#define N 59050
//三进制
int tri[12]={0,1,3,9,27,81,243,729,2187,6561,19683,59049};
int map[151][11];
int dp[2]
;
//前一状态,当前状态
int info_pre[11],info_cur[11];
int n,m,pass;
//初始化
void Init()
{
memset(map,0,sizeof(map));
memset(dp,-1,sizeof(dp));
}
//转化 十进制
int switch_ten(int *p)
{
int i,ans;
for(i=1,ans=0;i<=m;i++){
ans += p[i]*tri[i];
}
return ans;
}
//转化 三进制
void switch_tri(int t,int *p)
{
int i;
for(i=1;i<=m;i++){
p[i] = t%3;
t/=3;
}
return ;
}
void dfs(int i,int j,int cnt,int stata)
{
int k;
dp[i%2][stata] = Max(dp[i%2][stata],cnt);
if(j >= m ) return ;
if(!info_pre[j] && !info_pre[j+1] && !info_cur[j] && !info_cur[j+1]){
// 3*2 排列时
info_cur[j] = info_cur[j+1] = 2;
k = switch_ten(info_cur);
dfs(i,j+2,cnt+1,k);
info_cur[j]=info_cur[j+1]=0;
}
if(j < m-1 && !info_cur[j] && !info_cur[j+1] && !info_cur[j+2]){
// 2*3 排列时
info_cur[j] = info_cur[j+1] = info_cur[j+2] = 2;
k = switch_ten(info_cur);
dfs(i,j+3,cnt+1,k);
info_cur[j] = info_cur[j+1] = info_cur[j+2] = 0;
}
dfs(i,j+1,cnt,stata);
return ;
}
int main()
{

int t,k,i,j,l,stata,ans;
scanf("%d",&t);
while(t--){
Init();
scanf("%d%d%d",&n,&m,&k);
while(k--){
scanf("%d%d",&i,&j);
map[i][j] = 1;
}
for(i=1;i<=m;i++){
info_pre[i] = map[1][i] + 1;
}
stata = switch_ten(info_pre);
dp[1][stata] = 0;
for(i=2;i<=n;i++){

for(j=0;j<tri[m+1];j++)dp[i%2][j] = -1;

for(j=0;j<tri[m+1];j++){

if(dp[(i+1)%2][j] == -1)continue;

switch_tri(j,info_pre);

for(l=1;l<=m;l++){
if(map[i][l])
info_cur[l] = 2;
else info_cur[l] = Max(info_pre[l]-1,0);
}
pass = dp[(i+1)%2][j];
dfs(i,1,pass,switch_ten(info_cur));
}
}
for(i=0,ans=0;i<tri[m+1];i++){
ans = Max(ans,dp[n%2][i]);
}
printf("%d\n",ans);

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: