ABC 224 | E - Integers on Grid

题目描述

给定一个H×W的矩阵,给定N个三元组(ri,wi,ai),表示(ri,wi)位置的值为ai,其余格子上数值为0
Takahashi将分别以(ri,wi)作为起始位置,从当前位置走到同行或者同列且数值大于当前位置的格子处,输出从(ri,wi)出发最多能走几步?

数据范围

  • 2H,W2×105
  • 1Nmin(2×105,HW)
  • 1riH,1ciW
  • 1ai109

解题思路

使用动态规划算法解决问题。

  • 状态表示

dp[i]:(ri,ci)出发能够走的最大步数

由于除给出的(ri,ci)位置,其余位置都是0,所以只需对给出的n个位置进行状态表示,因为从(ri,ci)只能转移到某个(rj,cj)

  • 状态转移

    • 由于只能转移到数值更大的位置,所以为保证可以进行状态转移,需要对n个位置的数值进行降序遍历,同时为避免数值相等导致错误转移,需要将数值相等的位置全部进行状态转移,然后统一进行数组更新。
    • 由于只能转移到同行或者同列的位置,所以需要找出当前位置所在行ri以及所在列ci最大的dp值,将该值记为rmax[ri],cmax[ci],在每轮状态转移后进行数组更新。
  • 语法问题

    • map默认从小到大进行排序,该题需要进行倒序遍历
    for(auto t = mp.rbegin(); t != mp.rend(); t ++){  //对map进行降序遍历
        for(auto i : t -> second) f[i] = max(rmax[r[i]], cmax[c[i]]);  //t是迭代器,只能使用'->'
        for(auto i : t -> second) {
            rmax[r[i]] = max(f[i] + 1, rmax[r[i]]);
            cmax[c[i]] = max(f[i] + 1, cmax[c[i]]);
        }
    }
    

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <vector>

using namespace std;

const int N = 2e5 + 10;

int h, w, n;
int r[N], c[N], a[N];
int rmax[N], cmax[N];
int f[N];
map<int, vector<int>> mp;

int main()
{
    scanf("%d%d%d", &h, &w, &n);
    for(int i = 1; i <= n; i ++){
        scanf("%d%d%d", &r[i], &c[i], &a[i]);
        mp[a[i]].push_back(i);
    }

    for(auto t = mp.rbegin(); t != mp.rend(); t ++){ 
        for(auto i : t -> second) f[i] = max(rmax[r[i]], cmax[c[i]]);  
        for(auto i : t -> second) {
            rmax[r[i]] = max(f[i] + 1, rmax[r[i]]);
            cmax[c[i]] = max(f[i] + 1, cmax[c[i]]);
        }
    }

    for(int i = 1; i <= n; i ++) printf("%d\n", f[i]);
    return 0;
}

posted @   小菜珠的成长之路  阅读(124)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示