首页 > 其他分享 >【牛客小白75】D 矩阵 【bfs+优先队列】

【牛客小白75】D 矩阵 【bfs+优先队列】

时间:2023-07-01 12:46:14浏览次数:49  
标签:node yy int xx bfs 牛客 75 dp

题目

https://ac.nowcoder.com/acm/contest/60063/D

题意是说,给你一张 \(n * m(n,m \leq 10^3)\) 大小的01地图,当前点下一步只能走到相邻的点上,如果这两个点值相同,则代价为2,否则代价为1,问从(1,1)走到(n,m)最少代价是多少

思路

首先很容易想到只往右下走是错的,有可能往左和往上走总代价更小

那么状态转移就不能两层循环解决了,有点类似dp,但是实现需要用到bfs,bfs的依据是从当前代价最小的状态的点开始往其他地方转移,因此使用优先队列

具体来说,因为从第一个点开始走的路径上的值一定是010101...或者101010....,所以先根据从起点开始走到的奇数or偶数步给每个点一个初始的cost,再把他们修改为相应的0或1;

bfs的时候如果当前的代价大于这个点的最小代价,就continue掉

code

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1000 + 10;
ll dp[N][N], a[N][N], add[N][N];
bool vis[N][N];
int n, m;
int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
struct node{
    int x;
    int y;
    ll t;
    bool operator < (const node &aa) const {
        return t > aa.t;   
    }
};

void solve() {
    memset(dp, 0x3f3f3f3f, sizeof(dp));
    dp[1][1] = 0;
    priority_queue<node> q;
    q.push((node){1, 1, 0});
    while(!q.empty()) {
        node u = q.top(); q.pop();
        // cout << u.x << ' ' << u.y << ' ' << u.t << endl;   ///
        if(u.t > dp[u.x][u.y]) continue;
        for(int i = 0; i < 4; i++) {
            int xx = u.x + dir[i][0], yy = u.y + dir[i][1];
            if(xx < 1 || yy < 1 || xx > n || yy > m) continue;
            if(dp[u.x][u.y] + add[xx][yy] < dp[xx][yy]) {
                dp[xx][yy] = dp[u.x][u.y] + add[xx][yy];
                q.push((node){xx, yy, dp[xx][yy]});
            }
        }
    }
    return;
}

int main(){
    cin >> n >> m;
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= m; j++) {
            scanf("%1d", &a[i][j]);
            if((i + j) % 2) add[i][j] = (a[i][j] == a[1][1]) + 1;
            else add[i][j] = (a[i][j] != a[1][1]) + 1;
        }
    }
    solve();
    cout << dp[n][m] << endl;
	return 0;
} 

标签:node,yy,int,xx,bfs,牛客,75,dp
From: https://www.cnblogs.com/re0acm/p/17519120.html

相关文章

  • 牛客小白月赛75
    C方豆子题意按照题意模拟,详见链接思路看到的第一眼就想递归,之后发现稍微有点麻烦没那么直接难度不高,模拟水题代码//>>>Qiansui#include<map>#include<set>#include<list>#include<stack>#include<cmath>#include<queue>#include<deque>#include<cstdio&g......
  • CF1753 题解
    CF1753题解A首先我们发现,我们可以将序列一部分取反,将1变-1,-1变1的操作每次将总和增加2,所以如果初始和的绝对值为奇数则无解。我们发现,一段区间可以拆成若干个长度为2和1的小区间(+-+-+-+-....)变成(+-+-+-...)。我们假设初始都是长度为1的小区间,这时答案等于所有数的总和。我们......
  • P3975 [TJOI2015] 弦论 题解
    一、题目描述:给你一个长度为$n$的字符串,字符串由$26$个小写字母组成,求第$k$大的字串。给定参数$t$:$t=0:\位置不同的相同字串只算一个。$$t=1:\位置不同的相同字串算作多个。$若字串数量不足$k$个,输出$-1$。数据范围:$1\le......
  • 牛客图论 (第一章)
    F棋盘覆盖#include<bits/stdc++.h>usingnamespacestd;#definelllonglongconstintN=105,M=N*N*4,ID=N*N+N;intn,m;inthead[ID],ver[M],nxt[M],tot;boolban[N][N];intdx[]={1,-1,0,0},dy[]={0,0,1,-1};intmatch[ID];boolv[ID];......
  • 题解 P8757 [蓝桥杯 2021 省 A2] 完美序列
    题解P8757[蓝桥杯2021省A2]完美序列题意如果一个序列是单调递减的,而且除了第一个数以外的任何一个数都是上一个数的因数,则称这个序列为一个完美序列。一个序列中的一个子序列如果是完美序列,则称为该序列的一个完美子序列。一个序列的最长完美子序列长度,称为该序列的完美......
  • hdu 1575(矩阵快速幂)
    题解:矩阵快速幂模板题。#include<stdio.h>#include<string.h>constintN=10;structMat{intg[N][N];}res,ori;intn,k;Matmultiply(Matx,Maty){Mattemp;memset(temp.g,0,sizeof(temp.g));for(inti=0;i<n;i++)......
  • WP CTF-Web 攻防世界 GFSJ0475 get_post
    「场景」进入场景后提示请用GET方式提交一个名为a,值为1的变量「思路」根据提示在url后加上?a=1,回车发送请求。出现新提示。请再以POST方式随便提交一个名为b,值为2的变量打开brupsuite,配置本地代理为brupsuite中proxy的地址和端口号,刷新浏览器页面,brupsuite捕获到请求......
  • 牛客练习赛112 B qsgg and Subarray
    这里介绍两种解法,贪心和二分核心:只要某一个区间和为0,则所有包含该区间的和都为0贪心根据题意是求出所有⊕和为0的子区间的个数,我们按a[i]来分类,每次求出以a[i]为末尾,区间和为0的区间个数,对于a[i]来说,要想u~i的区间和为0,则需要包含所有a[i]中位为1都有0与之对应,如果u~i的区间和......
  • Coloring Tree (牛客多校) (BFS序列妙用+ f(n)-f(n+1)+ 组合数学)
    题目大意:给一个树,然后有k种颜色可以给树上色权值是2个相同颜色节点的最短距离问让权值为D的方案数 题解:首先要让2个节点为D,怎么处理呢?利用f(D)-f(D+1)即可因为问的是2个相同颜色点的最短距离,因此直接bfs用一个bfs序列然后在bfs一下,因为之前co......
  • Distance to Work (牛客多校) (圆和简单多边形相交面积 + 二分半径)
    #include<bits/stdc++.h>usingnamespacestd;constdoubleeps=1e-9;//浮点数精度控制#defineVectorpoint#definePointpointconstdoublePI=acos(-1);structPoint{doublex,y;Point(doublex=0,doubley=0):x(x),y(y){}friendVe......