zoukankan      html  css  js  c++  java
  • [BZOJ1177][Apio2009]Oil

    [BZOJ1177][Apio2009]Oil

    试题描述

    采油区域 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公司雇佣你来写一个程序,帮助计算出他们可以承包的区域的石油储量之和的最大值。

    输入

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

    输出

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

    输入示例

    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

    输出示例

    208

    数据规模及约定

    0 < n, m < 2501, 答案不超过int, 0 < k < min{ n, m }且保证有方案

    题解

    马丹智障题。。。我来吐槽一下:

    1.) 这题是一道恶心dp题(我分了14种情况讨论)

    2.) 这题大视野题面上没有范围,并且此题“讨论”中所发的范围是错的!

    3.) 这题数据有问题,不能用任何读入优化

    4.) 这题卡内存

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    #include <vector>
    #include <queue>
    #include <cstring>
    #include <string>
    #include <map>
    #include <set>
    using namespace std;
    
    #define maxn 2505
    #define LL int
    #define h f[0]
    #define t g[0]
    int n, m, K;
    LL S[maxn][maxn], f[2][maxn][maxn], g[2][maxn][maxn];
    
    LL sum(int x1, int y1, int x2, int y2) { return S[x2][y2] - S[x1][y2] - S[x2][y1] + S[x1][y1]; }
    
    int main() {
    //	freopen("data.in", "r", stdin);
    	scanf("%d%d%d", &n, &m, &K);
    //	n = read(); m = read(); K = read();
    	LL ans = 0;
    	for(int i = 1; i <= n; i++)
    		for(int j = 1; j <= m; j++) {
    			int tmp; scanf("%d", &tmp);
    			S[i][j] = S[i-1][j] - S[i-1][j-1] + S[i][j-1] + tmp;
    		}
    	
    	f[0][K][K] = S[K][K];
    	for(int i = K; i <= n; i++)
    		for(int j = K; j <= m; j++) {
    			f[0][i][j] = max(max(f[0][i-1][j], f[0][i][j-1]), sum(i-K, j-K, i, j));
    			f[1][i][j] = max(max(f[1][i-1][j], f[1][i][j-1]), sum(i-K, j-K, i, j) + max(f[0][i-K][j], f[0][i][j-K]));
    		}
    	g[0][n-K+1][m-K+1] = sum(n-K, m-K, n, m);
    	for(int i = n-K+1; i; i--)
    		for(int j = m-K+1; j; j--) {
    			g[0][i][j] = max(max(g[0][i+1][j], g[0][i][j+1]), sum(i-1, j-1, i+K-1, j+K-1));
    			g[1][i][j] = max(max(g[1][i+1][j], g[1][i][j+1]), sum(i-1, j-1, i+K-1, j+K-1) + max(g[0][i+K][j], g[0][i][j+K]));
    		}
    	for(int i = 1; i <= n-K+1; i++)
    		for(int j = 1; j <= m-K+1; j++) {
    			LL tmp = sum(i-1, j-1, i+K-1, j+K-1);
    			ans = max(ans, tmp + f[1][i-1][m]);
    			ans = max(ans, tmp + f[1][n][j-1]);
    			ans = max(ans, tmp + g[1][1][j+K]);
    			ans = max(ans, tmp + g[1][i+K][1]);
    			ans = max(ans, tmp + f[0][i-1][j+K-1] + g[0][1][j+K]);
    			ans = max(ans, tmp + f[0][i-1][m] + g[0][i][j+K]);
    			ans = max(ans, tmp + f[0][i-1][m] + g[0][i+K][1]);
    			ans = max(ans, tmp + f[0][i+K-1][j-1] + g[0][i+K][1]);
    			ans = max(ans, tmp + f[0][n][j-1] + g[0][i+K][j]);
    			ans = max(ans, tmp + f[0][n][j-1] + g[0][1][j+K]);
    		}
    	memset(h, 0, sizeof(h));
    	h[K][m-K+1] = sum(0, m-K, K, m);
    	for(int i = K; i <= n; i++)
    		for(int j = m-K+1; j; j--)
    			h[i][j] = max(max(h[i-1][j], h[i][j+1]), sum(i-K, j-1, i, j+K-1));
    	memset(t, 0, sizeof(t));
    	t[n-K+1][K] = sum(n-K, 0, n, K);
    	for(int i = n-K+1; i; i--)
    		for(int j = K; j <= m; j++)
    			t[i][j] = max(max(t[i+1][j], t[i][j-1]), sum(i-1, j-K, i+K-1, j));
    	for(int i = 1; i <= n-K+1; i++)
    		for(int j = 1; j <= m-K+1; j++) {
    			LL tmp = sum(i-1, j-1, i+K-1, j+K-1);
    			ans = max(ans, tmp + t[i+K][m] + h[i+K-1][j+K]);
    			ans = max(ans, tmp + t[i+K][j+K-1] + h[n][j+K]);
    			ans = max(ans, tmp + t[1][j-1] + h[i-1][j]);
    			ans = max(ans, tmp + t[i][j-1] + h[i-1][1]);
    		}
    	
    	printf("%d
    ", ans);
    	
    	return 0;
    }
    
  • 相关阅读:
    监控里的主码流和子码流是什么意思
    监控硬盘容量计算
    一个能让你了解所有函数调用顺序的Android库
    电工选线
    oracle linux dtrace
    list all of the Oracle 12c hidden undocumented parameters
    Oracle Extended Tracing
    window 驱动开发
    win7 x64 dtrace
    How to Use Dtrace Tracing Ruby Executing
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/5424556.html
Copyright © 2011-2022 走看看