当前位置:网站首页>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;
}
边栏推荐
猜你喜欢
2022-08-01 第八组 曹雨 泛型 枚举
APP专项测试:流量测试
小程序毕设作品之微信美食菜谱小程序毕业设计成品(7)中期检查报告
[Niu Ke brush questions-SQL big factory interview questions] NO4. Travel scene (a taxi)
Raspberry Pi information display small screen, display time, IP address, CPU information, memory information (C language), four-wire i2c communication, 0.96-inch oled screen
复现gallerycms字符长度限制短域名绕过
联邦学习在金融领域的发展和应用
Mini Program Graduation Works WeChat Food Recipe Mini Program Graduation Design Finished Product (8) Graduation Design Thesis Template
Use Jenkins for continuous integration, this knowledge point must be mastered
SOM Network 1: Principles Explained
随机推荐
leetcode 204. Count Primes 计数质数 (Easy)
线上故障排查方案
统计单词数
Small program -- subcontracting
小程序毕设作品之微信美食菜谱小程序毕业设计成品(6)开题答辩PPT
10年稳定性保障经验总结,故障复盘要回答哪三大关键问题?|TakinTalks大咖分享
感觉自己好傻
毕业十年,财富自由:那些比拼命努力更重要的事,从来没人会教你
2022 版 MySQL 巅峰教程,收藏好,慢慢看
Postman batch test interface detailed tutorial
将vim与系统剪贴板的交互使用
Safe fifth after-school exercise
xctf攻防世界 Web高手进阶区 webshell
求解多元多次方程解的个数
1. @Component注解的原理剖析
一种灵活的智能合约协作方式
SAP Spartacus Accessibility E2E 端到端测试
小程序毕设作品之微信美食菜谱小程序毕业设计成品(8)毕业设计论文模板
selenium无头,防检测
小程序毕设作品之微信体育馆预约小程序毕业设计成品(2)小程序功能