链接:http://acm.hdu.edu.cn/showproblem.php?pid=5556
思路:直接枚举祖先的选不选,然后把选上的附近的删掉,然后剩下的点按做最大独立集.
祖先那边选了x个,剩下的没被删掉的点共n个,把x+y是奇数的放一边,偶数的放另一边,匹配数是m,那么结果就是x+n-m。
代码:
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <string>
#include <ctime>
#define fur(i,a,b) for(int i=(a);i<=(b);i++)
#define furr(i,a,b) for(int i=(a);i>=(b);i--)
#define cl(a) memset((a),0,sizeof(a))
using namespace std;
// (づ°ω°)づe★-------------------------------------------------
int n, m, ans;
char mp[12][12];
int dx[]={-1,0,1,0};
int dy[]={0,1,0,-1};
bool has[20],used[105],E[105][105],ok[12][12];
int linker[105];
inline int id(int i, int j){return (i-1)*m+j;}
bool dfs(int u){
fur(i,1,n)fur(j,1,m){
if((i+j)%2!=0) continue;
if(ok[i][j] && !used[id(i,j)] && E[u][id(i,j)]){
used[id(i,j)]=true;
if(linker[id(i,j)]==-1 || dfs(linker[id(i,j)])){
linker[id(i,j)]=u;
return true;
}
}
}
return false;
}
int pp(){
int ret = 0;
memset(linker,-1,sizeof(linker));
fur(i,1,n){
fur(j,1,m){
if((i+j)%2==0) continue;
cl(used);
if(dfs(id(i,j))) ret++;
}
}
return ret;
}
void solve(int x){
bool nowhas[20];cl(nowhas);
fur(i,0,9){
if(x&(1<<i)) nowhas[i]=true;
if(nowhas[i]&&!has[i]) return;
}
fur(i,1,n)fur(j,1,m)ok[i][j]=true;
fur(i,1,n){
fur(j,1,m){
char c = mp[i][j];
if(c!='.'){
ok[i][j]=false;
if(nowhas[c-'0']){
fur(k,0,3){
char cc = mp[i+dx[k]][j+dy[k]];
if(cc!=c && cc>='0'&&cc<='9' && nowhas[cc-'0']&&nowhas[c-'0'])
return;
ok[i+dx[k]][j+dy[k]]=false;
}
}
}
}
}
cl(E);
int ret = 0;
fur(i,0,9) ret+=nowhas[i];
fur(i,1,n){
fur(j,1,m){
if(!ok[i][j]) continue;
ret++;
fur(k,0,3){
int nxtx = i+dx[k],nxty = j+dy[k];
if(nxtx>n||nxtx<1||nxty>m||nxty<1) continue;
if(ok[nxtx][nxty]){
if((i+j)%2==1) E[id(i,j)][id(nxtx,nxty)]=true;
else E[id(nxtx,nxty)][id(i,j)]=true;
}
}
}
}
int p = pp();
ret-=p;
if(ret>ans)
ans=ret;
}
int main(){
int T;
scanf("%d",&T);
fur(kase,1,T){
cl(has);cl(mp);
scanf("%d%d",&n,&m);
fur(i,1,n) scanf("%s",mp[i]+1);;
fur(i,1,n)fur(j,1,m)
if(mp[i][j]!='.') has[mp[i][j]-'0']=true;
ans=0;
fur(i,0,1023) solve(i);
printf("Case #%d: %d\n",kase,ans);
}
return 0;
}