领地选择【前缀和+DP】

题目描述

作为在虚拟世界里统帅千军万马的领袖,小Z认为天时、地利、人和三者是缺一不可的,所以,谨慎地选择首都的位置对于小T来说是非常重要的。

首都被认为是一个占地C*C的正方形。小Z希望你寻找到一个合适的位置,使得首都所占领的位置的土地价值和最高。

输入输出格式

输入格式:
第1行:三个正整数N,M,C,表示地图的宽和长以及首都的边长。

第2∼N+1行:第i+1行包含M个整数,表示了地图上每个地块的价值。价值可能为负数。

输出格式:
一行,两个整数X、Y,表示首都左上角的坐标。

输入输出样例

输入样例#1: 复制
3 4 2
1 2 3 1
-1 9 0 2
2 0 1 1
输出样例#1: 复制
1 2
说明

对于60%的数据:N、M≤50。

对于90%的数据:N、M≤300。

对于100%的数据:N、M≤1000,C≤min(N,M)。

分析:一看到这题,首先想到的是暴力枚举(即使知道不可以但是条件反射),一看数据范围:1000,O(n^4)显然超时。那么我们来想想暴力枚举为什么超时:首先我们枚举了i,j两行作为起始行和终点行,k,l两列作为起始列和终点列。再仔细思考了一番后我们发现,由于题目说得是c*c的方阵(固定了大小),我们就可以制造一个窗口在上面滑动(看不懂也没关系,不重要),这就代表着j=i+c-1的,于是我们就不用再枚举j。时间复杂度降了一个指数。可是O(n^3)仍然超时啊?考虑继续优化:题目求的是矩阵的和,可以联想到降维前缀和。代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<stack>
using namespace std;
long long a[1001][1001],sum[2001][2001];
inline int read()
{
    int f=1,x=0;
    char s=getchar();
    while(s<'0'||s>'9')
    {
        if(s=='-')
        f=-f;
        s=getchar();
    }
    while(s>='0'&&s<='9')
    {
        x=x*10+s-48;
        s=getchar();
    }
    return x*f;
}
int main()
{
    int n=read(),m=read(),c=read(),i,j,ans=-0x7fffffff,tot,ans1,ans2;//ans初始化为负无穷,因为有可能一个正数也没有
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m;j++)
        {
            a[i][j]=read();
            sum[i][j]=sum[i-1][j]+a[i][j];//sum【i】【j】表示第j列的1到i行所有数的和
        }
    }
    for(i=1;i<=n-c+1;i++)//由于这个矩阵是c*c,所以i<=n-c+1
    {
        j=i+c-1;//j可以随即求出
        tot=0;//初始化
        for(int k=1;k<=c;k++)
        {
            tot+=sum[j][k]-sum[i-1][k];//先计算第一个矩阵的大小
        }
        if(ans<tot)//更新
        {
            ans1=i;
            ans2=1;
            ans=tot;
        }
        for(int k=c+1;k<=m;k++)//枚举接下来的矩阵
        {
            tot-=sum[j][k-c]-sum[i-1][k-c];//优化:减去最左边的
            tot+=sum[j][k]-sum[i-1][k];//加上最右边的
            if(ans<tot)//更新
            {
                ans1=i;
                ans2=k-c+1;
                ans=tot;
            }
        }
    }
    printf("%d %d",ans1,ans2);//输出
    return 0;
}

谢谢各位,有错误及时提出

posted @   最爱丁珰  阅读(68)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示