怎么会~怎么会~就变成了
查看原帖
怎么会~怎么会~就变成了
1305692
xiangixuan楼主2025/7/2 20:03

WA 0pts~

#include<bits/stdc++.h>
#define int long long
#define P 12345678
using namespace std;

int n, m;
int x[16], y[16];

int tot, g[1024], f[64][1024];

bitset<8> tmp[16];
void dfs(int d, int s){
	if(d>=tot) {
		int cnt=n*m;
		for(int i=0; i<n; ++i)
			for(int j=0; j<m; ++j)
				if(tmp[i][j]) --cnt;
		g[s]=cnt;
		return;
	}
	dfs(d+1, s);
	for(int i=max(x[d+1]-1, 0ll); i<=min(x[d+1]+1, n-1); ++i)
		for(int j=max(y[d+1]-1, 0ll); j<=min(y[d+1]+1, m-1); ++j)
			tmp[i][j]=1;
	dfs(d+1, s^(1<<d));
	for(int i=max(x[d+1]-1, 0ll); i<=min(x[d+1]+1, n-1); ++i)
		for(int j=max(y[d+1]-1, 0ll); j<=min(y[d+1]+1, m-1); ++j)
			tmp[i][j]=0;
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> n >> m;
	for(int i=0; i<n; ++i) {
		string s;
		cin >> s;
		for(int j=0; j<m; ++j)
			if(s[j]=='X')
				x[++tot]=i, y[tot]=j;
	}
	dfs(0, (1<<tot)-1);
	
	f[0][0]=1;
	for(int i=1; i<=n*m; ++i)
		for(int j=0; j<(1<<tot); ++j) {
			f[i][j]=f[i-1][j]*max(g[j]-i+1, 0ll)%P;
			for(int k=0; k<tot; ++k)
				if((j>>k)&1)
					f[i][j]=(f[i][j]+f[i-1][j-(1<<k)])%P;
		}
	
	cout << f[n*m][(1<<tot)-1] << '\n';
	return 0;
}

f[i][j]表示从小到大填,已经填完1->i,局部最小点的填写情况为j的方案数.

g[i]代表局部最小点在i状态下能填的位置数量(就是不被 未被填的局部最小点 九方格所覆盖的位置数量)

那位大佬帮忙看看思路有什么问题. QwQ

2025/7/2 20:03
加载中...