| Time Limit: 15000MS | Memory Limit: 30000K | |
| Total Submissions: 8763 | Accepted: 3352 | |
| Case Time Limit: 5000MS | ||
Description

Input
Output
Sample Input
2 6 6 5 1 4 4 6 2 2 3 6 6 4 6 5 4 3 3 6 1 6 2 6 4
Sample Output
3 4
题意:给定n*m的一个区域,有若干损坏的格子,用2*3的砖铺,最多放多少块砖。
三进制压缩dp,研究好久,仍感吃力,只好硬着头皮往下坚持。
代码:
/* ***********************************************
Author :rabbit
Created Time :2014/3/14 15:40:30
File Name :F.cpp
************************************************ */
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
typedef long long ll;
const int maxn=60010;
int vis[155][15],dp[2][maxn],A[11],P[11],Q[11];
int n,m,K,mask;
int getstate(int f[]){
int res=0;
for(int i=1;i<=m;i++)res+=f[i]*A[i-1];
return res;
}
void getback(int x,int f[]){
for(int i=1;i<=m;i++)f[i]=x%3,x/=3;
}
void dfs(int i,int x,int num){//:i,i-1层都空;1:i层为空,i-1层被占;2:i层被占。
if(x>m)return;
int cur=(i+1)&1,nxt=i&1,k=getstate(Q);
dp[nxt][k]=max(dp[nxt][k],dp[cur][getstate(P)]);
if(x<=m-1&&(P[x]==0&&P[x+1]==0)&&(Q[x]==0&&Q[x+1]==0)){
Q[x]=Q[x+1]=2;
int kk=getstate(Q);
dp[nxt][kk]=max(dp[nxt][kk],num+1);
dfs(i,x+2,num+1);
Q[x]=Q[x+1]=0;
}
if(x<=m-2&&(!Q[x]&&!Q[x+1]&&!Q[x+2])){
Q[x]=Q[x+1]=Q[x+2]=2;
int kk=getstate(Q);
dp[nxt][kk]=max(dp[nxt][kk],num+1);
dfs(i,x+3,num+1);
Q[x]=Q[x+1]=Q[x+2]=0;
}
dfs(i,x+1,num);
}
int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
A[0]=1;for(int i=1;i<=10;i++)A[i]=3*A[i-1];
int T;scanf("%d",&T);
while(T--){
scanf("%d%d%d",&n,&m,&K);int x,y;
memset(vis,0,sizeof(vis));
for(int i=0;i<K;i++){
scanf("%d%d",&x,&y);
vis[x][y]=1;
}
memset(dp,-1,sizeof(dp));
memset(P,0,sizeof(P));
memset(Q,0,sizeof(Q));
for(int i=1;i<=m;i++)P[i]=vis[1][i]+1;
dp[1][getstate(P)]=0;
mask=A[m];
for(int i=2;i<=n;i++){
int cur=(i+1)&1,nxt=i&1;
memset(dp[nxt],-1,sizeof(dp[nxt]));
for(int j=0;j<mask;j++){
if(dp[cur][j]==-1)continue;
getback(j,P);
for(int x=1;x<=m;x++){
if(vis[i][x])Q[x]=2;
else{
Q[x]=P[x]-1;
if(Q[x]<0)Q[x]=0;
}
}
dfs(i,1,dp[cur][j]);
}
}
int ans=0;
for(int i=0;i<mask;i++)ans=max(ans,max(dp[0][i],dp[1][i]));
cout<<ans<<endl;
}
return 0;
}
POJ 1038 状态压缩dp,布布扣,bubuko.com
原文:http://blog.csdn.net/xianxingwuguan1/article/details/21240063