LightOJ 1092 Lighted Panels 状压DP

Description

You are given an R x C 2D grid consisting of several light panels. Each cell contains either a '*' or a '.''*' means the panel is on, and '.' means it's off. If you touch a panel, its state will be toggled. That means, if you touch a panel that's on, it will turn off, and if you touch a panel that's off, it will turn on. But if we touch a panel, all its horizontal, vertical, and diagonal adjacent panels will also toggle their states.

Now you are given the configuration of the grid. Your goal is to turn on all the lights. Print the minimum number of touches required to achieve this goal.

Input

Input starts with an integer T (≤ 125), denoting the number of test cases.

Each test case starts with two integers R (1 ≤ R ≤ 8) and C (1 ≤ C ≤ 8). Then there will be R lines each containing C characters ('*' or '.').

Output

For each test case, print the case number and the minimum number of touches required to have all the light panels in the board on at the same time. If it is not possible then print "impossible".

Sample Input

4

5 5

*****

*...*

*...*

*...*

*****

1 2

.*

3 3

**.

**.

...

4 4

*...

**..

..**

...*

Sample Output

Case 1: 1

Case 2: impossible

Case 3: 2

Case 4: 10

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <cmath>
#define INF 0x3f3f3f3f
using namespace std;
int n,m;
int dp[10][260][260],ret[300][300],sta[10],opt[300];
char str[20];
int cal(int opt,int sat){
int res=sat,tmp=opt;
int ii=0;
while(tmp){
if(tmp&1){
if(ii>0) res^=(1<<(ii-1));
res^=(1<<ii);
if(ii<m-1) res^=(1<<(ii+1));
}
tmp=tmp>>1;
ii++;
}
//cout<<sat<<' '<<opt<<' '<<res<<endl;
return res;
}
int cnt_opt(int op){
int tmp=op;
int res=0;
while(tmp){
if(tmp&1) res++;
tmp=tmp>>1;
}
return res;
}
void init(){
for(int i=0;i<n;++i)
for(int j=0;j<(1<<m);++j)
for(int k=0;k<(1<<m);++k)
dp[i][j][k]=INF;
memset(sta,0,sizeof(sta));
for(int i=0;i<(1<<m);++i){
opt[i]=cnt_opt(i);
for(int j=0;j<(1<<m);++j){
ret[j][i]=cal(i,j);
}
}
}
int main()
{

int T,cas=1;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
init();
for(int i=0;i<n;++i){
scanf("%s",str);
for(int j=m-1;j>=0;--j)
if(str[j]=='.') sta[i]+=(1<<(m-1-j));
//cout<<sta[i]<<endl;
}
int ans=INF;
if(n==1){
for(int i=0;i<(1<<m);++i){
if(ret[sta[0]][i]==0) ans=min(ans,opt[i]);
}
if(ans==INF) printf("Case %d: impossible\n",cas++);
else printf("Case %d: %d\n",cas++,ans);
continue;
}
dp[0][sta[0]][sta[1]]=0;
for(int i=0;i<(1<<m);++i){
dp[0][ret[sta[0]][i]][ret[sta[1]][i]]=min(dp[0][ret[sta[0]][i]][ret[sta[1]][i]],opt[i]);
}
for(int i=0;i<n-2;++i)
for(int j=0;j<(1<<m);++j)
for(int k=0;k<(1<<m);++k)
if(dp[i][j][k]!=INF){
for(int op=0;op<(1<<m);++op){
if(ret[j][op]==0){
//cout<<j<<' '<<k<<' '<<op<<endl;
dp[i+1][ret[k][op]][ret[sta[i+2]][op]]=min(dp[i+1][ret[k][op]][ret[sta[i+2]][op]],dp[i][j][k]+opt[op]);
}
}
//cout<<dp[1][sta[1]][sta[2]]<<endl;
}
for(int i=0;i<(1<<m);++i)
for(int j=0;j<(1<<m);++j)
for(int k=0;k<(1<<m);++k){
if(ret[i][k]==0&&ret[j][k]==0){
ans=min(ans,dp[n-2][i][j]+opt[k]);
}
}
if(ans==INF) printf("Case %d: impossible\n",cas++);
else printf("Case %d: %d\n",cas++,ans);
}
return 0;
}


• 本文已收录于以下专栏：

Light OJ 1092 Lighted Panels （状压DP）

1092 - Lighted Panels     PDF (English) Statistics Forum Time Limit: 3 second(s) Memory ...
• jncsw
• 2016年07月13日 14:28
• 156

LightOJ 1092 Lighted Panels（状压+高斯消元）

Lighted Panels Time Limit: 3000MS Memory Limit: 32768KB 64bit IO Format: %lld & %llu Su...
• mrlry
• 2016年08月15日 19:26
• 252

[状压dp] lightoj 1092 Lighted Panels

• gdymind
• 2016年07月13日 12:58
• 449

Light OJ 1092 Lighted Panels (状压)

• qq_26572969
• 2016年03月25日 11:52
• 244

对状压dp的一点理解

• benTuTuT
• 2017年04月12日 21:51
• 851

状压DP 入门题

• sinat_34336698
• 2016年08月06日 16:33
• 1619

状压DP问题

• u014355480
• 2015年08月17日 15:00
• 878

状压DP小结

• cbcbcbz
• 2017年07月23日 10:40
• 180

状压DP入门题集锦

POJ 3254 Corn Fields 题意： 一块n*m的田，1表示这个地方可以种植，0代表这个地方不能种植。植物种植还必须满足两株植物不能相邻（横竖都不行）。问共有几种种植方法，而且当...
• Codeblocksm
• 2016年03月05日 10:52
• 404

【总结】状压DP

• qq_21436421
• 2017年02月18日 21:30
• 288

举报原因： 您举报文章：LightOJ 1092 Lighted Panels 状压DP 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)