《P11248 [GESP202409 七级] 矩阵移动》

题目背景

对应的选择、判断题:试题 - GESP 202409 C++ 七级 - 洛谷有题

题目描述

小杨有一个 n×m 的矩阵,仅包含 01? 三种字符。矩阵的行从上到下编号依次为 1,2,...,n,列从左到右编号依次为 1,2,...,m。小杨开始在矩阵的左上角 (1,1),小杨只能向下或者向右移动,最终到达右下角 (n,m) 时停止,在移动的过程中每经过一个字符 1 得分会增加一分(包括起点和终点),经过其它字符则分数不变。小杨的初始分数为 0 分。

小杨可以将矩阵中不超过 x 个字符 ? 变为字符 1。小杨在修改矩阵后,会以最优的策略从左上角移动到右下角。他想知道自己最多能获得多少分。

输入格式

第一行包含一个正整数 t,代表测试用例组数,接下来是 t 组测试用例。对于每组测试用例,一共 n+1 行。

第一行包含三个正整数 n,m,x,含义如题面所示。

之后 n 行,每行一个长度为 m 的仅含 01? 的字符串。

输出格式

对于每组测试用例,输出一行一个整数,代表最优策略下小杨的得分最多是多少。

输入输出样例

输入 #1复制

复制代码
2
3 3 1
000
111
01?
3 3 1
000
?0?
01?

输出 #1复制

复制代码
4
2

说明/提示

样例 1 解释

对于第二组测试用例,将 (2,1) 或者 (3,3) 变为 1 均是最优策略。

数据规模与约定

子任务编号 数据点占比 t n,m x
1 30% ≤5 ≤10 =1
2 30% ≤10 ≤500 ≤30
3 40% ≤10 ≤500 ≤300

对全部的测试数据,保证 1≤t≤10,1≤n,m≤500,1≤x≤300,保证所有测试用例 n×m 的总和不超过 2.5×105。

代码实现:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
const int INF = -1e9;
const int MAXX = 305;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    while(t--)
    {
        int n,m,x;
        cin >> n >> m >> x;
        vector<string> s(n+1);
        for(int i=1;i<=n;i++)
        {
            string tmp;
            cin >> tmp;
            s[i] = " " + tmp;
        }
        vector<vector<vector<int>>> dp(n+2, vector<vector<int>>(m+2, vector<int>(x+2, INF)));
        if(s[1][1] == '1')
        {
            dp[1][1][0] = 1;
        }
        else if(s[1][1] == '0')
        {
            dp[1][1][0] = 0;
        }
        else
        {
            dp[1][1][0] = 0;
            if(1 <= x) dp[1][1][1] = 1;
        }

        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(i == 1 && j == 1) continue;
                char c = s[i][j];
                for(int k=0;k<=x;k++)
                {
                    int up = INF, left = INF;
                    if(i>1) up = dp[i-1][j][k];
                    if(j>1) left = dp[i][j-1][k];
                    int pre = max(up, left);
                    if(pre == INF) continue;
                    if(c == '1')
                    {
                        dp[i][j][k] = max(dp[i][j][k], pre + 1);
                    }
                    else if(c == '0')
                    {
                        dp[i][j][k] = max(dp[i][j][k], pre);
                    }
                    else
                    {
                        dp[i][j][k] = max(dp[i][j][k], pre);
                        if(k+1 <= x)
                        {
                            dp[i][j][k+1] = max(dp[i][j][k+1], pre + 1);
                        }
                    }
                }
            }
        }
        int ans = 0;
        for(int k=0;k<=x;k++)
        {
            ans = max(ans, dp[n][m][k]);
        }
        cout << ans << '\n';
    }
    return 0;
}
相关推荐
wzdark11 小时前
基于矩阵的动态规划路径问题性能优化4
线性代数·矩阵·动态规划
船厂电气自动化ai大模型2 天前
AI大模型与数学 第75课 基、维度、向量空间坐标
数据结构·线性代数·算法·机器学习·推荐算法
hansang_IR3 天前
【题解】P4456 [CQOI2018] 交错序列(矩阵乘法)
c++·线性代数·算法
浪里镖客3 天前
位姿转换矩阵中旋转与平移转换的问题--解决方案
线性代数·矩阵
hansang_IR4 天前
【题解】P5364 [SNOI2017] 礼物
c++·线性代数·算法
吴声子夜歌7 天前
ApacheCommons——commons-math3(科学计算与线性代数)(一)
java·线性代数·算法·apache
AI_yangxi7 天前
口碑好的短视频矩阵系统
线性代数·矩阵
微三云生态系统架构师-彭丹8 天前
矩阵拼团系统设计:先付款先排队的订单排序与自动返本算法
线性代数·算法·矩阵
张欣-男9 天前
5分钟理解线性代数v2
人工智能·线性代数·机器学习
张欣-男9 天前
3分钟理解线性代数
线性代数·算法