闲谈:和数独规则差不多--然后可以直接按数独1的方法进行就好了..数独1没写题解吧...这里补下QAQ.
1.首先观察计数,我们观察层数会发现,假如我们下标从0开始,那么在我们填一个数(x,y)时,付出的代价是min(min(8-x,x),min(8-y,y))+6;那么假设我们填的数是val,那么得分就是val*min(min(8-x,x),min(8-y,y))+6;
2.和数独1一样,我们可以预先处理出两个数组,一个ones,一个mp.第一个判断二进制数中有几个1,第二个用来判断一个二进制数是2的几次方.为什么要这两个预处理呢?第一个ones我们是用来,在对于每次选择分支少的进行剪枝的,第二个mp枚举可填位子的时候填哪个数.
3.先记录下有多少空是空的的,我们优先填空中选择最少的空,这样搜索的分支将会更小,然后进行递归dfs即可,用个ans记录答案,一旦搜完就更新ans.
4.由于每行,每列,每个九宫格都只能出现1~9,我们用二进制数存一下每行,每列,每个九宫格使用情况.开始将他们赋值为(1<<9)-1.然后一旦一个数填了t,我们就将这个数-(1<<t).emm这就是整个过程了,下面就是看代码怎么写了QAQ
下面就是代码了:

#include <bits/stdc++.h>
using namespace std;
const int N=9;
int a[N][N],cnt=0,ans=-1,val=0,line[N],row[N],cell[N][N];
int ones[1<<9],mp[1<<9];
inline int get(int x,int y,int z)//填哪个数,然后算出来的价值
{
    return z*(min(min(8-x,x),min(8-y,y))+6);
}

inline int lowbit(int x)//在可选集合,一个一个数的填.
{
    return x&(-x);
}

void draw(int x,int y,int t)//在x,y中填t.
{
    a[x][y]=t;
    row[x]-=(1<<(t-1));
    line[y]-=(1<<(t-1));
    cell[x/3][y/3]-=(1<<(t-1));
}

inline int f(int x,int y)
{
    return cell[x/3][y/3]&row[x]&line[y];//算出可以填的位子
}

void dfs(int cnt,int val)//dfs填了所有数,然后更新ans
{
    if(cnt==0) {if(val>ans) ans=val;return;}//递归出口.
    int vv=10;//先赋值最大可以填的.
    int x,y;//记录坐标.
    for(int i=0;i<N;i++)
    {
        for(int j=0;j<N;j++)
        {
            if(ones[f(i,j)]<vv&&!a[i][j])
            {
                vv=ones[f(i,j)];
                x=i,y=j;
            }
        }
    }//找到分支最小的点.
    //cout<<x<<' '<<y<<' '<<endl;
    for(int i=f(x,y);i;i-=(lowbit(i)))
    {
        int t=mp[lowbit(i)]+1;
        draw(x,y,t);
        dfs(cnt-1,val+get(x,y,t));
        row[x]+=(1<<(t-1));
        line[y]+=(1<<(t-1));
        cell[x/3][y/3]+=(1<<(t-1));
        a[x][y]=0;
    }
}

void init()
{
    for(int i=0;i<N;i++) row[i]=line[i]=(1<<9)-1;
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<3;j++)
        {
            cell[i][j]=(1<<9)-1;
        }
    }
    for(int i=0;i<N;i++) mp[1<<i]=i;
    for(int i=0;i<(1<<N);i++)
    {
        for(int j=i;j;j-=lowbit(j))  ones[i]++;
    }
}

int main()
{
    init();
    for(int i=0;i<N;i++)
    {
        for(int j=0;j<N;j++)
        {
            cin>>a[i][j];
            if(a[i][j])
            {
                draw(i,j,a[i][j]);
                val+=get(i,j,a[i][j]);
            }
            else cnt++;
        }
    }
    dfs(cnt,val);//n个点需要填,现在当前的价值是val了.
    cout<<ans<<endl;
    return 0;
}

感谢辛格大佬QAQ,又出bug了