搜索剪枝 TLE #9 #13 求助
查看原帖
搜索剪枝 TLE #9 #13 求助
569235
w9095楼主2023/7/24 16:15

思路:把每个没有填的点按可填数字多少从小到大排序,依据排序后的顺序搜索。

卡不动了,求助qaq。

#include <bits/stdc++.h>
using namespace std;
int sc[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}};
int sg[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}};
struct node
{
	int x,y,q;
}w[100];
int d[10][10],h[10][10],l[10][10],g[10][10],s[100],bh[10],bl[10],bg[10],p=0,cnt=0,ans=0;
bool cmp(struct node a,struct node b)
{
	return a.q<b.q;
}

inline void dfs(int now,int sum)
{
	int x=w[now].x,y=w[now].y;
	if(now==cnt+1)
	   {
	    if(sum>ans)ans=sum;
	   	return;
	   }
	if(sum+(s[cnt]-s[now-1])*10<=ans)return;
	for(register int i=1;i<=9;i++)
	    if(!h[x][i]&&!l[y][i]&&!g[sg[x][y]][i])
	       {
	       	h[x][i]=l[y][i]=g[sg[x][y]][i]=1;
	       	dfs(now+1,sum+sc[x][y]*i);
	       	h[x][i]=l[y][i]=g[sg[x][y]][i]=0;
		   }
	return;
}

int main()
{
    for(register int i=1;i<=9;i++)
        for(register int j=1;j<=9;j++)
            {
            	scanf("%d",&d[i][j]);
            	if(d[i][j]!=0)h[i][d[i][j]]=1,l[j][d[i][j]]=1,g[sg[i][j]][d[i][j]]=1;
            	p+=d[i][j]*sc[i][j];
			}
	for(register int i=1;i<=9;i++)
	    for(register int j=1;j<=9;j++)
	        if(d[i][j]==0)++cnt,w[cnt].x=i,w[cnt].y=j,bh[i]++,bl[j]++,bg[sg[i][j]]++;
	for(register int i=1;i<=cnt;i++)w[i].q=bh[w[i].x]+bl[w[i].x]+bg[sg[w[i].x][w[i].y]];
	sort(w+1,w+cnt+1,cmp);
	for(register int i=1;i<=cnt;i++)
	    s[i]=s[i-1]+sc[w[i].x][w[i].y];
	dfs(1,0);
	if(ans==0)printf("-1");
	else printf("%d",ans+p);
    return 0;
}
2023/7/24 16:15
加载中...