[Bzoj 1177][Apio2009] Oil 前缀和+递推

1177: [Apio2009]Oil

Time Limit: 15 Sec Memory Limit: 162 MB

Submit: 1569 Solved: 632

[Submit][Status][Discuss]

Description

采油区域 Siruseri政府决定将石油资源丰富的Navalur省的土地拍卖给私人承包商以建立油井。被拍卖的整块土地为一个矩形区域,被划分为M×N个小块。 Siruseri地质调查局有关于Navalur土地石油储量的估测数据。这些数据表示为M×N个非负整数,即对每一小块土地石油储量的估计值。 为了避免出现垄断,政府规定每一个承包商只能承包一个由K×K块相连的土地构成的正方形区域。 AoE石油联合公司由三个承包商组成,他们想选择三块互不相交的K×K的区域使得总的收益最大。 例如,假设石油储量的估计值如下: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 8 8 8 8 1 1 1 1 8 8 8 8 8 1 1 1 1 8 8 8 8 8 1 1 1 1 1 1 1 8 8 8 1 1 1 1 1 1 1 1 8 8 8 1 1 1 1 1 1 9 9 9 1 1 1 1 1 1 9 9 9 如果K = 2, AoE公司可以承包的区域的石油储量总和为100, 如果K = 3, AoE公司可以承包的区域的石油储量总和为208。 AoE公司雇佣你来写一个程序,帮助计算出他们可以承包的区域的石油储量之和的最大值。

Input

输入第一行包含三个整数M, N, K,其中M和N是矩形区域的行数和列数,K是每一个承包商承包的正方形的大小(边长的块数)。接下来M行,每行有N个非负整数表示这一行每一小块土地的石油储量的估计值

Output

输出只包含一个整数,表示AoE公司可以承包的区域的石油储量之和的最大值。

Sample Input

9 9 3

1 1 1 1 1 1 1 1 1

1 1 1 1 1 1 1 1 1

1 8 8 8 8 8 1 1 1

1 8 8 8 8 8 1 1 1

1 8 8 8 8 8 1 1 1

1 1 1 1 8 8 8 1 1

1 1 1 1 1 1 8 8 8

1 1 1 1 1 1 9 9 9

1 1 1 1 1 1 9 9 9

Sample Output

208

题目链接http://www.lydsy.com/JudgeOnline/problem.php?id=1177

题意

询问n*m的矩阵中找三个k*k的矩阵的最大值

思路

分情况讨论:

故需维护以右下为点的k*k的矩阵和,以维护左上,右上,左下,右下的最大K*k值;

代码

#include<iostream>
#include<stdio.h>
#include<string.h>
#define maxn  2005
using namespace std;
int a[maxn][maxn],b[maxn][maxn],c[maxn][maxn],s[maxn][maxn],d[maxn][maxn];
int n,m;
int aa;
int k;
int main()
{
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    {
        scanf("%d",&aa);
        s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+aa;
    }

    for(int i=n;i>=k;i--)
    for(int j=m;j>=k;j--)
    s[i][j]-=s[i-k][j]+s[i][j-k]-s[i-k][j-k];   

    for(int i=k;i<=n;i++)
    for(int j=k;j<=m;j++)
    a[i][j]=max(s[i][j],max(a[i-1][j],a[i][j-1]));

    for(int i=k;i<=n;i++)
    for(int j=m;j>=k;j--)
    b[i][j]=max(s[i][j],max(b[i-1][j],b[i][j+1]));

    for(int i=n;i>=k;i--)
    for(int j=k;j<=m;j++)
    c[i][j]=max(s[i][j],max(c[i+1][j],c[i][j-1]));

    for(int i=n;i>=k;i--)
    for(int j=m;j>=k;j--)
    d[i][j]=max(s[i][j],max(d[i+1][j],d[i][j+1]));

    int ans=0;

    for(int i=k;i<=n-k;i++)
    for(int j=k;j<=m-k;j++)
    ans=max(ans,a[i][j]+b[i][j+k]+c[i+k][m]);

    for(int i=k+k;i<=n;i++)
    for(int j=k;j<=m-k;j++)
    ans=max(ans,c[i][j]+d[i][j+k]+a[i-k][m]);

    for(int i=k;i<=n-k;i++)
    for(int j=k;j<=m-k;j++)
    ans=max(ans,a[i][j]+c[i+k][j]+b[n][j+k]);

    for(int i=k;i<=n-k;i++)
    for(int j=k+k;j<=m;j++)
    ans=max(ans,b[i][j]+d[i+k][j]+a[n][j-k]);

    for(int i=k+k;i<=n-k;i++)
    for(int j=k;j<=m-k;j++)
    ans=max(ans,c[i][j]+d[i][j+k]+a[i-k][m]);

    for(int i=k;i<=n;i++)
    for(int j=k+k;j<=m;j++)
    ans=max(ans,s[i][j]+a[n][j-k]+b[n][j+k]);

    for(int i=k+k;i<=n-k;i++)
    for(int j=k;j<=m;j++)
    ans=max(ans,s[i][j]+a[i-k][m]+c[i+k][m]);

    printf("%d\n",ans);
}
时间: 2024-10-11 18:07:05

[Bzoj 1177][Apio2009] Oil 前缀和+递推的相关文章

BZOJ 1177 [Apio2009]Oil(递推)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1177 [题目大意] 给出一个矩阵,从中选出3个k*k且不相交的矩阵,使得其总和最大 [题解] 只要处理四个方向的前缀最大值,就可以分类比较得到答案. [代码] #include <cstdio> #include <algorithm> using namespace std; #define rep(i,a,b) for(int i=a;i<=b;i++) #d

BZOJ 1089 严格n元树 (递推+高精度)

题解:用a[i]表<=i时有几种树满足度数要求,那么这样就可以递归了,a[i]=a[i-1]^n+1.n个节点每个有a[i-1]种情况,那么将其相乘,最后加上1,因为深度为0也算一种.那么答案就是a[n]-a[n-1].然后就是高精度的问题了,发现很久没有现码高精度没手感了,连高进度加法进位都出了些问题,需要特别注意. #include <cstdio> #include <cstring> #include <algorithm> using namespace

BZOJ 2431 HAOI2009 逆序对数列 递推

题目大意:求1~n的所有排列中有多少种逆序对为k的方案数 令f[i][j]为前i个数的排列中逆序对数为j的方案数 那么我们将第i个数插入1~i-1的排列中 可以产生0~i-1个逆序对 于是有 f[i][j]=Σf[i-1][k] (j-i+1<=k<=j) 维护前缀和即可 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 1010

BZOJ 1197 HNOI2006 花仙子的魔法 递推

题目大意:求n维空间下的m个球最多可以将空间分为多少个区域 VFK的题解: http://vfleaking.blog.163.com/blog/static/174807634201321193348312/ 自己看吧.... 我还在纠结零维空间内放入一个零维的球之后空间到底会被分成几份..... #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> us

BZOJ 1045 糖果传递 题解 【递推乱搞就对了

1045: [HAOI2008] 糖果传递 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3505  Solved: 1626[Submit][Status][Discuss] Description 有n个小朋友坐成一圈,每人有ai个糖果.每人只能给左右两人传递糖果.每人每次传递一个糖果代价为1. Input 第一行一个正整数n<=987654321,表示小朋友的个数.接下来n行,每行一个整数ai,表示第i个小朋友得到的糖果的颗数. Outpu

BZOJ 1009 HNOI 2008 GT考试 递推+矩乘

1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 3679  Solved: 2254[Submit][Status][Discuss] Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字. 他的不吉利数学A1A2...Am(0<=Ai<=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2.

【BZOJ 1177】 [Apio2009]Oil

1177: [Apio2009]Oil Time Limit: 15 Sec  Memory Limit: 162 MB Submit: 1044  Solved: 404 [Submit][Status][Discuss] Description 采油区域 Siruseri政府决定将石油资源丰富的Navalur省的土地拍卖给私人承包商以建立油井.被拍卖的整块土地为一个矩形区域,被划分为M×N个小块. Siruseri地质调查局有关于Navalur土地石油储量的估测数据.这些数据表示为M×N个非

实用算法的分析与程序设计——递推法(贮油点 含算法分析、代码)

倒推法 所谓倒推法就是在不知初始值的情况下,经某种递推关系而获知问题的解或目标,再倒过来,推知它的初始条件,因为这类问题的运算过程是一一映射的,故可分析得其递推公式.然后再从这个解或目标出发,采用倒推手段,一步步地倒推到这个问题的初始陈述. 贮油点 一辆重型卡车欲穿越1000公里的沙漠,卡车耗油为1升/公里,卡车总载油能力为500公升,显然卡车装一次油是过不了沙漠的.因此四级必须设法在沿途建立几个储油点,使卡车能顺利穿越沙漠,试问司机如何建立这些贮油点?每一贮油点应存多少汽油,才能使卡车以消耗最

实用算法的分析与程序设计——递推法(倒推法)

倒推法就是在不知初始值的情况下,经某种递推关系而获知问题的解或目标,再倒过来,推知它的初始条件.因为这类问题的运算过程是一一映射的,故可分析得其递推公式,然后再从这个解或目标出发,采用倒推手段,一步步地倒推到这个问题的初始陈述. 贮油点 一辆重型卡车欲穿过1000公里的沙漠,卡车耗油为1升/公里,卡车总载油能力为500公升,显然卡车装一次油是过不了沙漠的,因此四级必须设法在沿途建立几个贮油点,使卡车能顺利穿越沙漠,试问司机如何建立这些贮油点?每一贮油点应存多少汽油,才能使卡车以消耗最少汽油的代价