[USACO11MAR] Brownie Slicing G题解(二分+二维前缀和+矩阵分割)

[USACO11MAR] Brownie Slicing G

题目地址

P3017 [USACO11MAR] Brownie Slicing G

思路

二分最大化最小值

切割思路:

一行一行进行切割,如果这一行可以切割出b块大于等于mid的块,就开始切割下一行

如果无法切割出b块,就把正在切割的行与下一行拼起来一起切割

最后通过能切割出b块的水平块块够不够a条来判断m是否合适

代码

cpp 复制代码
#include <iostream>

using namespace std;

int a[1010][1010], s[1010][1010];
int r, c, x, y;

bool check(int m) {
    int lrow = 0;
    int rows = 0;
    for (int i = 1; i <= r; i ++) {
        int num = 0, sum = 0;
        for (int j = 1; j <= c; j ++) {
            if (sum + (s[i][j]-s[i][j-1])-(s[lrow][j]-s[lrow][j-1]) < m)
                sum += (s[i][j]-s[i][j-1])-(s[lrow][j]-s[lrow][j-1]);
            else {
                sum = 0;
                num ++;
            }
        }
        if (num >= y) {
            lrow = i;
            ++ rows;
        }

    }
    return rows >= x;
}

int main() {

    cin >> r >> c >> x >> y;
    for (int i = 1; i <= r; i ++)
        for (int j = 1; j <= c; j ++) {
            cin >> a[i][j];
            s[i][j] = s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
        }
    int left = 0, right = s[r][c];
    //m 越小越容易成功
    while (left < right) {
        int m = left + right + 1 >> 1;
        if (check(m))
            left = m;
        else
            right = m - 1;
    }
    cout << left;

    return 0;
}
相关推荐
啊阿狸不会拉杆34 分钟前
《算法导论》第 32 章 - 字符串匹配
开发语言·c++·算法
小学生的信奥之路1 小时前
洛谷P3817题解:贪心算法解决糖果分配问题
c++·算法·贪心算法
曙曙学编程2 小时前
stm32——GPIO
c语言·c++·stm32·单片机·嵌入式硬件
你知道网上冲浪吗2 小时前
【原创理论】Stochastic Coupled Dyadic System (SCDS):一个用于两性关系动力学建模的随机耦合系统框架
python·算法·数学建模·数值分析
△曉風殘月〆2 小时前
Visual Studio中的常用调试功能(下)
c++·ide·visual studio·调试
武当豆豆2 小时前
C++编程学习(第25天)
开发语言·c++·学习
地平线开发者3 小时前
征程 6 | PTQ 精度调优辅助代码,总有你用得上的
算法·自动驾驶
Tisfy4 小时前
LeetCode 837.新 21 点:动态规划+滑动窗口
数学·算法·leetcode·动态规划·dp·滑动窗口·概率
CoovallyAIHub4 小时前
为高空安全上双保险!无人机AI护航,YOLOv5秒判安全带,守护施工生命线
深度学习·算法·计算机视觉
huangzixuan10074 小时前
08.18总结
算法·深度优先·图论