题解 CF1391D 【505】
程序员文章站
2024-02-24 12:53:34
...
这道题目的话看似没有头绪,我们分析一下。
偶数长度平方矩阵为:、、……
我们考虑是否可能同时满足所有 的矩阵 的个数为奇数,所有 的矩阵 的个数为奇数。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uD8pFpHw-1597048634801)(https://i.loli.net/2020/08/10/Wb7EZy8nuXHwVMl.png)]
如图,每个黑色正方形是一个 的矩阵,为了满足要求它们 的个数都为奇数,由 个 的矩阵拼成的 大矩阵为了复合要求也必须由奇数个 ,然后这和我们上面的东西矛盾,因为奇数 偶数,所以, 且 的矩阵,一定不能满足所有条件。
那么由于 ,所以我们分类讨论。
-
对于 ,答案显然为 。
-
对于 ,显然对于连续的 列,这两列 的个数必须奇偶性不相同,因为只有奇数+偶数=奇数。所以一共就只有 钟情况。
- 第 列 的个数为奇数,第 列 的个数为偶数……
- 第 列 的个数为偶数,第 列 的个数为奇数……
时间复杂度 。
-
对于 ,我们可以用状压 来做,我们设 表示第 列状态为 ,转移的话,我们枚举前一列的合法状态,对所有可行解取个 即可,最后不要忘记加上这 列修改的方格数。
不难发现,每个状态可以转移的状态数均为 ,因此此题复杂度为 , 倍常数,但这是可以 的。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
T RR=1;FF=0;char CH=getchar();
for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
FF*=RR;
}
int a[15][1000010],f[1000010][11];
vector<int>v[15];
bool check(int x,int y){//判断2个状态是否能相互转移
int a1=x&1,a2=(x>>1)&1,a3=(x>>2)&1;
int b1=y&1,b2=(y>>1)&1,b3=(y>>2)&1;
if((a1+a2+b1+b2)%2==0)return false;
if((a2+a3+b2+b3)%2==0)return false;
return true;
}
int work(int y,int x){//算修改了几个格子
int a1=x&1,a2=(x>>1)&1,a3=(x>>2)&1;
return (a[1][y]!=a1)+(a[2][y]!=a2)+(a[3][y]!=a3);
}
int main(){
int n,m;read(n);read(m);
if(n>=4&&m>=4){
puts("-1");
return 0;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
char ch=getchar();
for(;ch!='0'&&ch!='1';ch=getchar());
a[i][j]=(ch=='1');
}
if(n==1){
puts("0");
return 0;
}
if(n==2){
int ans1=0,ans2=0;
for(int j=1;j<=m;j++)
if((a[1][j]+a[2][j])%2!=(j&1))ans1++;
for(int j=1;j<=m;j++)
if((a[1][j]+a[2][j])%2!=((j&1)^1))ans2++;
cout<<min(ans1,ans2);
return 0;
}
for(int i=0;i<(1<<3);i++)
for(int j=0;j<(1<<3);j++)
if(check(i,j))
v[j].push_back(i);
for(int j=0;j<(1<<3);j++)f[1][j]=work(1,j);//边界
for(int i=2;i<=m;i++)
for(int j=0;j<(1<<3);j++){
f[i][j]=n*m+1;
for(auto k:v[j]){
f[i][j]=min(f[i][j],f[i-1][k]+work(i,j));
}
}
int ans=n*m+1;
for(int j=0;j<(1<<3);j++)ans=min(ans,f[m][j]);
cout<<ans;
return 0;
}
推荐阅读
-
题解 CF1391D 【505】
-
Can't connect to MySQL server on 'localhost' (10048)问题解决方法
-
mysql启动的error 2003和1067错误问题解决方法
-
【题解】Willem, Chtholly and Seniorious Codeforces 896C ODT
-
thinkPHP分组后模板无法加载问题解决方法
-
Java编程删除链表中重复的节点问题解决思路及源码分享
-
CCP-CSP认证考试 201803-1 跳一跳 c/c++题解
-
spring+springmvc整合mabytis时mapper注入失败问题解决方法
-
windows环境下Mysql中文乱码问题解决方法
-
java 中序列化NotSerializableException问题解决办法