poj 1038 Bugs Integrated,Inc.(状圧dp)
6048 ワード
http://poj.org/problem?id=1038
Bugs Integrated、Inc.
Time Limit: 15000 MS
メモリLimit: 30000 K
Total Submissions: 8917
Acceepted: 3404
Case Time Limit: 5000 MS
Description
Bugs Integrated、Inc.is a majorr majurmamajurmamamamamajururof advanced memomorychips.They ararlaunching productctctctctctctio of a a a a new aaaaw six teraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaartested carefullyand the bad ones are marked with a black maker.
Finally,the play of silicon is cut into memory chips.Each chip consists of 2*3(or 3*2)unit squares.Of course,no chip can contain any bad(marked)スクウェア.It might not be possible to cut the plate so that everry good square is a part of some memory chip.The copopopopoports to waste good squares as possible.The fore thery would like the khocut
Task
You are given the dimensions of several silicon ples and a list of all bad unit squares for each plate.Your task is to write a program that computtes for each plate the maximnumber of chips ap.
Input
The first line of the input file consists of a single integer D(1<=D==5)、denoting the number of silicon pltes.D blocks follw、each describing one silicon plate.The first line of of each block block ininininininggggggggggs=1=1=1=rererererererererererererererererereres=1=1=1=1=1=s=1=1=s=1=s=s=s=rereininininininininininininininininininininininininininininaces.N is the length of the plate、M is its height and K is the number of bad squares in the plate.The following K lineas contain a list of bad squares.Each line consists of two integers x and y(1<=x==N,1<=y=M)?coordinates of one bad square(the up per left square has coordination[1,1],the bottom right is[N,M])
Output
For each plate in the input file output a single line containing the maximnumber of memory chips that can be cut out of the plate.
Sample Input
CEOI 2002
N*Mの矩形を一つあげます.この矩形には2*3の矩形がいくつあるかと聞きました.条件としては、悪い点があります.悪い点は矩形を入れてはいけません.
M<=10ですので、形圧が可能です.3進数の状態は圧縮して、2はこの点が放すことができないことを表して、1はこの点が置くことができることを表していますが、その前の点は置くことができなくて、0はこの点が置くことができることを表しています.しかもその前の点も置くことができます.この行の状態で後ろの行を押し出した状態で、まず矩形を置かない状態に対して、この行為2では次の行が1となり、この行為1では次の行が0となり、この行為が0なら次の行も0となります.次の行に置かない状態で、この行を矩形にした状態で、2つの0を連続して前の行に対応する位置も0ならば、縦に長方形を置いてもいいです.0を連続して3つ置くと、長方形を横に置くことができます.悪い点があるので、矩形に悪い点があるかどうかを判断します.長方形を置くすべての状態を検索して更新できます.複雑度O(n*m*3^m).状圧dpを移行する際に、dfsで有効状態を検索して更新するのも良い最適化手段です.コードは以下の通りです
Bugs Integrated、Inc.
Time Limit: 15000 MS
メモリLimit: 30000 K
Total Submissions: 8917
Acceepted: 3404
Case Time Limit: 5000 MS
Description
Bugs Integrated、Inc.is a majorr majurmamajurmamamamamajururof advanced memomorychips.They ararlaunching productctctctctctctio of a a a a new aaaaw six teraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaartested carefullyand the bad ones are marked with a black maker.
Finally,the play of silicon is cut into memory chips.Each chip consists of 2*3(or 3*2)unit squares.Of course,no chip can contain any bad(marked)スクウェア.It might not be possible to cut the plate so that everry good square is a part of some memory chip.The copopopopoports to waste good squares as possible.The fore thery would like the khocut
Task
You are given the dimensions of several silicon ples and a list of all bad unit squares for each plate.Your task is to write a program that computtes for each plate the maximnumber of chips ap.
Input
The first line of the input file consists of a single integer D(1<=D==5)、denoting the number of silicon pltes.D blocks follw、each describing one silicon plate.The first line of of each block block ininininininggggggggggs=1=1=1=rererererererererererererererererereres=1=1=1=1=1=s=1=1=s=1=s=s=s=rereininininininininininininininininininininininininininininaces.N is the length of the plate、M is its height and K is the number of bad squares in the plate.The following K lineas contain a list of bad squares.Each line consists of two integers x and y(1<=x==N,1<=y=M)?coordinates of one bad square(the up per left square has coordination[1,1],the bottom right is[N,M])
Output
For each plate in the input file output a single line containing the maximnumber of memory chips that can be cut out of the plate.
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 Output3
4
ソurceCEOI 2002
N*Mの矩形を一つあげます.この矩形には2*3の矩形がいくつあるかと聞きました.条件としては、悪い点があります.悪い点は矩形を入れてはいけません.
M<=10ですので、形圧が可能です.3進数の状態は圧縮して、2はこの点が放すことができないことを表して、1はこの点が置くことができることを表していますが、その前の点は置くことができなくて、0はこの点が置くことができることを表しています.しかもその前の点も置くことができます.この行の状態で後ろの行を押し出した状態で、まず矩形を置かない状態に対して、この行為2では次の行が1となり、この行為1では次の行が0となり、この行為が0なら次の行も0となります.次の行に置かない状態で、この行を矩形にした状態で、2つの0を連続して前の行に対応する位置も0ならば、縦に長方形を置いてもいいです.0を連続して3つ置くと、長方形を横に置くことができます.悪い点があるので、矩形に悪い点があるかどうかを判断します.長方形を置くすべての状態を検索して更新できます.複雑度O(n*m*3^m).状圧dpを移行する際に、dfsで有効状態を検索して更新するのも良い最適化手段です.コードは以下の通りです
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<math.h>
#define nn 110000
#define inff 0x3fffffff
typedef long long LL;
using namespace std;
int n,m,k;
bool huai[200][20];
bool hu[200][20][200][20];
int dp[2][60000];
int po[20];
int w1[20],w2[20];
int ans,t;
void fuck(int x)
{
for(int i=0;i<m;i++)
{
printf("%d",x%3);
x/=3;
}
puts("");
}
bool check(int x1,int y1,int x2,int y2)
{
int i,j,g,e;
for(i=x1;i<=x2;i++)
{
for(j=y1;j<=y2;j++)
{
if(huai[i][j])
return true;
}
}
return false;
}
void init()
{
int i,j,g,e;
po[0]=1;
for(i=1;i<=m;i++)
po[i]=po[i-1]*3;
memset(hu,false,sizeof(hu));
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
for(g=i;g<=n;g++)
{
for(e=j;e<=m;e++)
{
hu[i][j][g][e]=check(i,j,g,e);
}
}
}
}
for(i=0;i<=1;i++)
{
for(j=0;j<po[m];j++)
dp[i][j]=-1;
}
dp[0][po[m]-1]=0;
}
void dfs(int id,int zt,int fc,int h)
{
if(id==m)
return ;
int ix;
if(id<m-1&&w2[id]==0&&w2[id+1]==0)
{
if(w1[id]==0&&w1[id+1]==0)
{
if(!hu[h-1][id+1][h+1][id+2])
{
ix=zt+2*po[id]+2*po[id+1];
dp[1-t][ix]=max(dp[1-t][ix],fc+1);
dfs(id+2,ix,fc+1,h);
}
}
if(id<m-2&&w2[id+2]==0)
{
if(!hu[h][id+1][h+1][id+3])
{
ix=zt+2*po[id]+2*po[id+1]+2*po[id+2];
dp[1-t][ix]=max(dp[1-t][ix],fc+1);
dfs(id+3,ix,fc+1,h);
}
}
}
dfs(id+1,zt,fc,h);
}
void solve()
{
int i,j,g,e;
int ix,tem,fc;
t=0;
for(i=0;i<n;i++)
{
for(j=0;j<po[m];j++)
{
if(dp[t][j]<0)
continue;
ix=j,tem=0;
for(g=0;g<m;g++)
{
w1[g]=ix%3;
ix/=3;
if(w1[g]==0)
w2[g]=0;
else
w2[g]=w1[g]-1;
tem+=w2[g]*po[g];
}
dp[1-t][tem]=max(dp[1-t][tem],dp[t][j]);
dfs(0,tem,dp[t][j],i);
}
memset(dp[t],-1,sizeof(t));
t=1-t;
}
ans=0;
for(i=0;i<po[m];i++)
{
ans=max(ans,dp[t][i]);
}
}
int main()
{
int d,i;
scanf("%d",&d);
while(d--)
{
scanf("%d%d%d",&n,&m,&k);
int u,v;
memset(huai,false,sizeof(huai));
for(i=1;i<=k;i++)
{
scanf("%d%d",&u,&v);
huai[u][v]=true;
}
init();
solve();
printf("%d
",ans);
}
return 0;
}