CF1955G GCD on a grid 做题记录

洛谷链接

我们暴力枚举可能的答案 \(k\),然后每一次检查时跑一遍 dp。
\(f_{i,j}\) 表示在格子 \((i,j)\) 是否可以满足有一条路径可以到达该格子且该格子是否为 \(k\) 的倍数,递推式即为 \(f_{i,j}=[k\mid a_{i,j} ]\operatorname{and} [f_{i-1,j} \operatorname{or} f_{i,j-1}]\) 最后的答案即是 \(f_{n,m}\)
时间复杂度 \(O(nm\sqrt{V})\),其中 \(V\) 是值域。

点击查看代码
bool check(int k) {
	m0(f);
	f[1][1]=1;
	For(i,1,n) For(j,1,m) {
		if(a[i][j]%k==0) {
			f[i][j]|=f[i-1][j]|f[i][j-1];
		}
	}
	return f[1][1]&f[n][m];
}
void work() {
	in2(n,m);
	For(i,1,n) inn(a[i],m);
	int g=__gcd(a[1][1],a[n][m]);
	int ans=0;
	
	for(int i=1;i*i<=g;i++){
		if(g%i==0) {
			if(check(i))
				ans=max(ans,i);
			if(check(g/i))
				ans=max(ans,g/i);
		}
	}
	cout<<ans<<'\n';
}
posted @ 2024-10-15 15:26  coding_goat_qwq  阅读(4)  评论(0编辑  收藏  举报