专栏文章
题解:AT_abc424_d [ABC424D] 2x2 Erasing 2
AT_abc424_d题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minsf7r1
- 此快照首次捕获于
- 2025/12/02 07:35 3 个月前
- 此快照最后确认于
- 2025/12/02 07:35 3 个月前
题意
给定一个矩阵,每个格子为白色或黑色。每次我们可以使一个黑色格子变为白色,求使得矩阵中没有 的黑色子矩阵的最小操作数。
做法
注意到 和 最大为 ,考虑状压 。
设 表示当前走到了第 行,当前行状态为 且满足在此行前不存在 的黑色子矩阵的最小操作次数。
设 表示当前走到了第 行,当前行状态为 且满足在此行前不存在 的黑色子矩阵的最小操作次数。
可以存储每一行的初始状态 ,预处理出每一行的合法状态 ,计算 到 的黑格变化个数。
用上一行的状态来更新这一行的答案,按位比对判断两行状态是否满足不存在 黑色子矩阵。
复杂度
代码
CPP#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
int T,h,w;
string s;
int sit[10],f[(1<<10)][10];
vector<pair<int,int> > e[10];
int sum(int x,int p){
cerr<<x<<" "<<p<<")))\n";
int sum = 0;
for(int i=0;i<w;i++){
if(!((x >> i) & 1) && !((p >> i) & 1)) sum++;
}
cerr<<sum<<"???\n";
return sum;
}
bool check(int x,int y){
for(int i=0;i<w;i++){
if(((x >> i) & 3) == 3 && ((y >> i) & 3) == 3) return false;
}
return true;
}
void solve(){
cin >> h >> w;
for(int i=1;i<=h;i++){
cin >> s;
for(int j=0;j<s.size();j++){
if(s[j]=='.') sit[i] += (1 << j);
}
}
for(int i=1;i<=h;i++){
for(int p=0;p<(1<<w);p++){
f[p][i] = INT_MAX;
if(!(sit[i] & p)) e[i].push_back({p,sum(sit[i],p)});
}
}
for(auto x : e[1]){
f[x.fi][1] = x.se;
}
for(int i=2;i<=h;i++){
for(auto x : e[i]){
for(auto y : e[i - 1]){
if(check(x.fi,y.fi)){
f[x.fi][i] = min(f[x.fi][i],f[y.fi][i-1] + x.se);
}
}
}
}
int ans = INT_MAX;
for(auto x : e[h]){
ans = min(ans,f[x.fi][h]);
}
cout << ans << "\n";
memset(sit,0,sizeof sit);
for(int i=1;i<=9;i++){
e[i].clear();
}
}
int main(){
cin >> T;
while(T--){
solve();
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...