当前位置:网站首页>1391D. 505 状压dp
1391D. 505 状压dp
2022-08-01 22:16:00 【Strezia】
D
状压dp, 2000
题意
给出一个 n × m ( n ≤ m ) n\times m(n\leq m) n×m(n≤m) 的 01 01 01矩阵,称任意一个边长为偶数的子正方形中1的个数为奇数的矩阵为好矩阵,求至少改多少个数,可以使其变为好矩阵。如果无论多少次操作都无法变为好矩阵,输出 − 1 -1 −1 。
思路
首先 n ≥ 4 n\geq 4 n≥4 的一定不行,因为 4 个 22 的矩阵个数为奇,则组成的 44 的矩阵个数为偶,于是考虑 n ≤ 3 n\leq 3 n≤3 的。
- n = 1 n=1 n=1 时,显然为 0 。
- n = 2 / 3 n = 2/3 n=2/3 时,设 f [ i ] [ s t a t e ] f[i][state] f[i][state] 表示前 i i i 列满足条件且第 i i i 列状态为 s t a t e state state 的最小操作数。显然 f [ i ] [ n o w ] f[i][now] f[i][now] 只和 f [ i − 1 ] [ p r e ] f[i-1][pre] f[i−1][pre] 有关,对于可以转移的状态,有 f [ i ] [ n o w ] = m i n ( f [ i ] [ n o w ] , f [ i − 1 ] [ p r e ] + c h a n g e ( n o w , i n i t ) ) f[i][now]=min(f[i][now], f[i-1][pre] + change(now, init)) f[i][now]=min(f[i][now],f[i−1][pre]+change(now,init)) 。其中 c h a n g e ( n o w , i n i t ) change(now,init) change(now,init) 即为初始的第 i i i 列到状态为 n o w now now 所需要改变的数。
所以现在只需要解决两个问题:如何判断 n o w now now 和 p r e pre pre 之间能够转移,如何求 c h a n g e ( n o w , i n i t ) change(now, init) change(now,init) 。
首先我们这样定义状态:对于 n = 3 , s t a t e = a [ 1 ] [ i ] ∗ 4 + a [ 2 ] [ i ] ∗ 2 + a [ 3 ] [ i ] n=3,state = a[1][i]*4+a[2][i]*2+a[3][i] n=3,state=a[1][i]∗4+a[2][i]∗2+a[3][i] ,对于 n = 2 , s t a t e = a [ 1 ] [ i ] ∗ 2 + a [ 2 ] [ i ] n=2,state = a[1][i]*2+a[2][i] n=2,state=a[1][i]∗2+a[2][i] ,第一个问题只需要判断2*2的矩阵中1的数量是否为奇数(若 n = 3 n=3 n=3 则需要判断2个2*2的矩阵),第二个问题只需要判断 n o w now now 和初始矩阵有几位不同 。
代码
int n, m;
int a[5][maxn];
int f[maxn][10];
int bit(int x, int y) {
return (x >> y) & 1;
}
int change(int x, int y) {
//x 当前状态 y 目标状态
int cnt = 0;
for(int i = 0; i < 4; i++) {
cnt += (bit(x, i) ^ bit(y, i));
}
return cnt;
}
int check2(int pre, int now) {
int cnt = bit(pre, 1) ^ bit(pre, 0) ^ bit(now, 1) ^ bit(now, 0);
return cnt;
}
int check3(int pre, int now) {
int cnt1 = bit(pre, 1) ^ bit(pre, 0) ^ bit(now, 1) ^ bit(now, 0);
int cnt2 = bit(pre, 1) ^ bit(pre, 2) ^ bit(now, 1) ^ bit(now, 2);
return cnt1 && cnt2;
}
void solve() {
memset(f, 0x3f, sizeof f);
cin >> n >> m;
if(n > 3) {
cout << -1 << endl;
return;
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
char c;
cin >> c;
a[i][j] = c - '0';
}
}
if(n == 1) {
cout << 0 << endl;
return;
}
if(n == 2) {
for(int i = 0; i < 4; i++) {
f[1][i] = change(i, a[1][1] * 2 + a[2][1]);
}
for(int j = 2; j <= m; j++) {
for(int now = 0; now < 4; now++) {
for(int pre = 0; pre < 4; pre++) {
if(check2(pre, now)) {
f[j][now] = min(f[j][now],
f[j-1][pre] + change(a[1][j]*2+a[2][j], now));
}
}
}
}
}
if(n == 3) {
for(int i = 0; i < 8; i++) {
f[1][i] = change(i, a[1][1] * 4 + a[2][1] * 2 + a[3][1]);
}
for(int j = 2; j <= m; j++) {
for(int now = 0; now < 8; now++) {
for(int pre = 0; pre < 8; pre++) {
if(check3(now, pre)) {
f[j][now] = min(f[j][now],
f[j-1][pre] + change(now, a[1][j]*4+a[2][j]*2+a[3][j]));
}
}
}
}
}
int ans = INF;
for(int i = 0; i <= 7; i++) chmin(ans, f[m][i]);
cout << ans << endl;
}
边栏推荐
猜你喜欢
随机推荐
Today's sleep quality record 74 points
xctf攻防世界 Web高手进阶区 web2
NgRx Store createSelector 的单步调试和源代码分析
小程序中的多表联合查询
Shell programming conditional statement
图论——强连通分量缩点+拓扑排序
Error creating bean with name ‘dataSource‘:Unsatisfied dependency expressed through field ‘basicPro
10 Practical Uses of NFTs (NFT System Development)
NgRx Selector 的 Memoization 特性学习笔记
KMP 字符串匹配问题
高等代数_证明_矩阵的行列式为特征值之积, 矩阵的迹为特征值之和
Analysis of the development trend of game metaverse
Mini Program Graduation Works WeChat Food Recipe Mini Program Graduation Design Finished Product (8) Graduation Design Thesis Template
03. GO language variable definition, function
求解多元多次方程解的个数
如何给 UE4 场景添加游戏角色
SOM网络1:原理讲解
毕业十年,财富自由:那些比拼命努力更重要的事,从来没人会教你
Recycling rental system 100% open source without encryption Mall + recycling + rental
【开源】Sentinel高性能高可用集群限流解决方案





![[ASM] Bytecode Operation MethodWriter](/img/54/a9f3ddd02ffc02aa965a083c03d322.jpg)

![[深入研究4G/5G/6G专题-48]: 5G Link Adaption链路自适应-4-下行链路自适应DLLA-PDCCH信道](/img/6b/d4ff120493e878fcf5c9aa728eced7.png)

