首页 > 其他分享 >题解 - 矩阵

题解 - 矩阵

时间:2024-07-28 15:55:19浏览次数:13  
标签:10 格子 int 题解 矩阵 样例 输入

题目描述

小明和小花知道学信息学竞赛的学生特别擅长做一些和矩阵相关的问题。例如,同学经常做的一个题目,给你一个 N × M 的矩阵,矩阵里面每个格子上都有一个数,要从左上角 (1,1),走到右下角 (N,M),每一步只能往下或者往右走,让你求经过的路径上数的总和最小。小明和小花发现这个问题太简单了,根本难不倒广大的 OIer。
于是,他们开始别出心裁了。
他们想着现在给你一个 01 矩阵(即里面每个格子上的数是 0 或者 1),仍旧让你从 (1,1) 走到 (N,M),每次只能往下面一个格子或者右边一个格子走。定义一条好路径是从起点到终点只经过 0 的格子。但是现在由于 1 的格子太多,所以可能无法完成这个任务。
于是,他们想出了修改操作,对于每个修改操作 (x1,y1)(x2,y2),表示把以 (x1,y1) 为左上角,以 (x2,y2) 为右下角的子矩阵里面每个格子里面的数进行反转,即 0 变成
1,1 变成 0。
问题是:最少需要多少次操作,才能使得这个矩阵存在好路径。现在请你来计算。

输入

输入的第一行是一个正整数 T,表示矩阵的个数。
对于每个矩阵:
输入第一行是 2 个正整数 N 和 M,表示矩阵的行数和列数。
接下来输入 N 行,每行有 M 个数,都是 0 或者 1,空格隔开。

输出

输出 T 个非负整数,每行一个数,表示最少需要的操作数,使得对应矩阵存在好路径。

样例

样例输入

【输入样例1】
1
3 3
0 1 1
0 1 0
1 1 0
【输入样例2】
1
5 5
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
【输入样例3】
2
10 10
0 0 0 0 0 1 0 0 1 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 1 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 1 0 0 0 1 0 1 1
10 10
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 0 1 1 1 1 1 1 1
1 1 0 1 1 1 1 1 1 1
1 0 1 1 1 1 1 1 1 1
1 0 1 1 1 1 1 1 1 1
1 1 0 1 1 1 1 1 0 0
1 1 1 1 1 1 1 1 1 1
1 0 1 1 1 1 1 1 0 1
1 1 1 1 1 1 1 1 1 1

样例输出

【输出样例1】
1
【输出样例2】
4
【输出样例3】
1
1

提示

请添加图片描述

分析

将最终路径看作01串,则翻转操作只会影响连续的一段数,

即转化为给定01串,问最少区间反转多少次,使得01串全变成0,线性dp即可

一维:

若a[i] == 0,则 f[i] = f[i - 1]

若a[i] != 0,则 f[i] = f[i - 1] + (a[i - 1]==0)

二维:

若a[i][j] == 0,则 f[i][j] = min(f[i][j - 1] + (a[i][j - 1] == 0),f[i - 1][j] + (a[i - 1][j] == 0))

若a[i][j] != 0,则 f[i][j] = min(f[i][j - 1],f[i - 1][j])

代码

#pragma GCC optimize(2)
  
#include<bits/stdc++.h>
   
using namespace std;
   
typedef long long LL;
   
const int N = 1e3 + 10,M = 1e6 + 10;
 
int n,m;
int a[N][N];
int f[N][N];
 
void solve(){
    cin >> n >> m;
    for(int i = 1;i <= n;i++)
        for(int j = 1;j <= m;j++)
            cin >> a[i][j];
 
    f[1][1] = a[1][1];
    for(int i = 2;i <= m;i++){
        if(a[1][i]) f[1][i] = f[1][i - 1] + (a[1][i - 1] == 0);
        else f[1][i] = f[1][i - 1];
    } 
    for(int i = 2;i <= n;i++){
        if(a[i][1]) f[i][1] = f[i - 1][1] + (a[i - 1][1] == 0);
        else f[i][1] = f[i - 1][1];
    }
 
    for(int i = 2;i <= n;i++)
        for(int j = 2;j <= m;j++){
            if(a[i][j]) f[i][j] = min(f[i][j - 1] + (a[i][j - 1] == 0),f[i - 1][j] + (a[i - 1][j] == 0));
            else f[i][j] = min(f[i][j - 1],f[i - 1][j]);
        }
 
    cout << f[n][m] << '\n';    
}
 
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
 
    int t;
    cin >> t;
    while(t--){
        solve();
    }
 
    return 0;
}

标签:10,格子,int,题解,矩阵,样例,输入
From: https://blog.csdn.net/qq_73162098/article/details/140562526

相关文章

  • luogu P1896 [SCOI2005] 互不侵犯 题解
    luoguP1896[SCOI2005]互不侵犯题解题目传送门思路状态压缩dp。状态压缩dp对于每一行,用一个\(n\)位二进制数表示每行的状态,则对于上下两行之间,设上行的数字为\(a\),下行的数字为\(b\),状态不合法有三种情况:\(a\operatorname{and}b\neq0\),即存在上行与下行同......
  • 洛谷P2440 题解
    P2440题解题目传送门提取关键词,题目需要的是数量大于$k$的最大$l$,考虑二分答案。可以二分枚举$l$的值,check函数中检验切割出该长度小段木头的个数,与$k$进行比较。小数据模拟例如,我们有五根木棍且$k=4$,分别为374106第一次循环$l=0,r=9,mid=4$。check函数中得到......
  • luogu P1896 [SCOI2005] 互不侵犯 题解
    luoguP1896[SCOI2005]互不侵犯题解题目传送门思路状态压缩dp。状态压缩dp对于每一行,用一个\(n\)位二进制数表示每行的状态,则对于上下两行之间,设上行的数字为\(a\),下行的数字为\(b\),状态不合法有三种情况:\(a\operatorname{and}b\neq0\),即存在上行与下行同......
  • Codeforces Round 962 (Div. 3) A - D详细题解(思路加代码Python,C++(垃圾灰名小白想
             吐槽一下,这次比赛不知道怎么的,可能是div3参加的人比较多吗,代码题解上去后全是inqueue,比赛的过程中我还看了提交的,80多页几千个提交全是inqueue,我的代码等了**半个多小时才运行,然后发现timelimit真的有点搞心态,思路在下一题我还要反过来去优化上一题,不过......
  • 逆序对的数量 - 题解
    逆序对的数量时间限制:C/C++1000MS,其他语言2000MS内存限制:C/C++64MB,其他语言128MB描述给定一个长度为\(n\)的整数数列,请你计算数列中的逆序对的数量。逆序对的定义如下:对于数列的第\(i\)个和第\(j\)个元素,如果满足\(i<j\)且\(a[i]>a[j]\),则其为一个逆序对;否则......
  • ABC364题解(D-G)
    D先对\(a\)从小到大排序。将题目转化成找到最小的\(d\),使得恰好有\(k\)个\(a_i\in[b-d,b+d]\)。对于每个询问\(b,k\),考虑二分答案。设待检查的答案为\(d\),二分找到最小的\(p1\)使得\(a_{p1}\geqb-d\)和最小的\(p2\)使得\(a_{p2}>b+d\),包含的数的个数即为\(......
  • 题解:P10481 Sudoku
    Sudoku来自蓝书思路优化搜索顺序,位运算常数优化。优化搜索顺序数独问题的搜索很简单,“搜索状态”就是每个位置上填了什么数。在每个状态下,选择一个未填位置,检查那些填入仍能满足数独条件(合法)的数字。构成的新的局面即为该状态的“分支”。足够暴力的写法为依次对每个位置进......
  • 2023CSP-j复赛题解
    csp-j题解update:2024.6.18-2024.6.25:重构题解第一题:小苹果原题洛谷P9748思路n表示当前长度求几天取完:每天取走\((n-1)/3+1\)个苹果,记录几天取完第\(n\)个苹果第几天被取走:当\(n\bmod3=0\)时被取走时间复杂度约为\(O(\log_n)\)#include<iostream>......
  • [ARC105C] Camels and Bridge 题解
    [ARC105C]CamelsandBridge题解出自梦熊比赛后,梦熊比赛出原题了,忘周知。也许更好的阅读体验思路全排列,差分约束,二分。全排列\(n\leq8\),且要指定顺序,易想到用全排列枚举所有状态。差分约束在全排列之后,需要求得每种状态的最短距离。定义所有骆驼的编号的集合为\(S\)......
  • ABC 364 F - Range Connect MST 题解
    一副扑克牌,去掉1到K,剩下就是我,赛后十秒过,我是joker。......