【題目描述】
const int N=11+5;
const int grade[10][10]{
{0,0,0,0,0,0,0,0,0,0},
{0,6,6,6,6,6,6,6,6,6},
{0,6,7,7,7,7,7,7,7,6},
{0,6,7,8,8,8,8,8,7,6},
{0,6,7,8,9,9,9,8,7,6},
{0,6,7,8,9,10,9,8,7,6},
{0,6,7,8,9,9,9,8,7,6},
{0,6,7,8,8,8,8,8,7,6},
{0,6,7,7,7,7,7,7,7,6},
{0,6,6,6,6,6,6,6,6,6},
};
const int part[10][10]{
{0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,2,2,2,3,3,3},
{0,1,1,1,2,2,2,3,3,3},
{0,1,1,1,2,2,2,3,3,3},
{0,4,4,4,5,5,5,6,6,6},
{0,4,4,4,5,5,5,6,6,6},
{0,4,4,4,5,5,5,6,6,6},
{0,7,7,7,8,8,8,9,9,9},
{0,7,7,7,8,8,8,9,9,9},
{0,7,7,7,8,8,8,9,9,9},
};
int n,m,t;
int i,j,k;
int maxx,num;
bool vis[N*10]; //記錄爲 0 的格子的狀態
bool vis_x[N][N],vis_y[N][N],vis_g[N][N]; //記錄橫行,縱列,小九宮格所包含的元素
int G[N][N]; //保存整個九宮格的數據
Pair p[N*10];
inline bool valid(int x,int aim){ //判斷此行,此列 及 小九宮格是否包含目標元素 aim
if(vis_x[ p[x].fr ][aim]) return false;
if(vis_y[ p[x].sc ][aim]) return false;
if(vis_g[ part[ p[x].fr ][ p[x].sc ] ][aim]) return false;
return true;
}
void DFS(int step)
{
if(step>num){
int ans=0;
for(int i=1;i<=9;i++){
for(int j=1;j<=9;j++){
ans+=G[i][j]*grade[i][j];
}
}
maxx=max(ans,maxx);
return ;
}
//尋找每個格子中擁有 最小選擇選擇數的格子進行填充
//可行性剪枝
int minn=inf,aim;
for(int i=1;i<=num;i++){ //枚舉還未填入的格子
if(!vis[i]){
int cur=0;
for(int j=1;j<=9;j++){ //枚舉每個可能填入的數
if( valid(i,j) ){
if(++cur==minn) break;
}
}
if(cur<minn){
minn=cur;
aim=i;
}
}
}
vis[aim]=1;
int x=p[aim].fr;
int y=p[aim].sc;
for(int i=1;i<=9;i++){
if( valid(aim,i) ){
G[x][y]=i;
vis_x[x][i]=1;
vis_y[y][i]=1;
vis_g[ part[x][y] ][i]=1;
DFS(step+1);
vis_x[x][i]=0;
vis_y[y][i]=0;
vis_g[ part[x][y] ][i]=0;
}
}
vis[aim]=0;
}
int main()
{
//IOS;
num=0;
for(i=1;i<=9;i++){
for(j=1;j<=9;j++){
cin>>G[i][j];
if(G[i][j]){
vis_x[i][ G[i][j] ]=1; //橫行上有了 G[i][j] 元素
vis_y[j][ G[i][j] ]=1; //縱列上有了 G[i][j] 元素
vis_g[ part[i][j] ][ G[i][j] ]=1; //小九宮格上有 G[i][j]元素
}
else{
num++;
p[num].fr=i; //橫行
p[num].sc=j; //縱列
}
}
}
maxx=-1;
DFS(1);
cout<<maxx<<endl;
//PAUSE;
return 0;
}