【codevs 1373】射命丸文

题目描述

在幻想乡,射命丸文是以偷拍闻名的鸦天狗。当然,文文的照相机可不止能够照相,还能够消除取景框里面所有的弹幕。假设现在文文面前有一块N行M列的弹幕群,每一个单位面积内有分值有num[i][j]的弹幕。相机的取景框可以将一块R行C列的弹幕消除,并且得到这一块区域内所有弹幕的分值(累加)。现在文文想要取得尽可能多的分值,请你计算出她最多能够得到的分值。

输入描述

第1行:4个正整数N,M,R,C
第2..N+1行:每行M个正整数,第i+1行第j个数表示num[i][j]

输出描述

第1行:1个整数,表示文文能够取得的最大得分

样例输入

3 5 2 3
5 2 7 1 1
5 9 5 1 5
3 5 1 5 3

样例输出

33

数据范围

对于60%的数据:1 <= N,M <= 200
对于100%的数据:1 <= N,M <= 1,000 1 <= R <= N, 1 <= C <= M 1 <= num[i][j] <= 1000
保证结果不超过2,000,000,000

用二维前缀和解,n^2预处理,n^2枚举矩形,O(1)查询

注意对于边界的处理

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN = 1000 + 5;
int map[MAXN][MAXN];
int n,m;
int r,c;
void get_sum()
{
    for(int i = 1;i <= n;i ++)
        for(int j = 1;j <= m;j ++)
            map[i][j] += map[i - 1][j] + map[i][j - 1] - map[i - 1][j - 1];
    return;
}
int sum(int a,int b,int c,int d)
{
    if(a < c)
        swap(a,c);
    if(b < d)
        swap(b,d);
    return map[a][b] - map[c - 1][b] - map[a][d - 1] + map[c - 1][d - 1];
}
int main()
{
    scanf("%d %d %d %d",&n,&m,&r,&c);
    for(int i = 1;i <= n;i ++)
        for(int j = 1;j <= m;j ++)
            scanf("%d",&map[i][j]);
    get_sum();
    int ans = 0;
    for(int i = 1;i <= n - r + 1;i ++)
        for(int j = 1;j <= m - c + 1;j ++)
            ans = max(ans,sum(i,j,i + r - 1,j + c - 1));
    printf("%d\n",ans);
    return 0;
}

关于二维前缀和

sum[i][j]表示这里写图片描述
修改的话套个BIT(和这个题无关)
引用下神犇的课件
这里写图片描述
这个题查询时一样的,可暴力枚举两端点
嗯,就是这样了

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值