枚举(分类讨论):BZOJ 1177: [Apio2009]Oil
2016-03-14 17:00
477 查看
1177: [Apio2009]Oil
Time Limit: 15 Sec Memory Limit: 162 MBSubmit: 1477 Solved: 589
[Submit]
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 31 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这道题很妙啊,其实只要分类讨论就可以了。
#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int maxn=1510; int Ul[maxn][maxn],Ur[maxn][maxn]; int Dl[maxn][maxn],Dr[maxn][maxn]; int a[maxn][maxn]; int sum(int x,int y,int k) { if(x<k||y<k)return 0; return a[x][y]-a[x-k][y]-a[x][y-k]+a[x-k][y-k]; } void Pre_Solve(int R,int C,int K) { for(int i=K;i<=R;i++) for(int j=K;j<=C;j++){ int S=sum(i,j,K); Ul[i][j]=S; Ur[i][j-K+1]=S; Dl[i-K+1][j]=S; Dr[i-K+1][j-K+1]=S; } for(int i=1;i<=R;i++) for(int j=1;j<=C;j++) Ul[i][j]=max(Ul[i][j],max(Ul[i-1][j],Ul[i][j-1])); for(int i=1;i<=R;i++) for(int j=C;j>=1;j--) Ur[i][j]=max(Ur[i][j],max(Ur[i-1][j],Ur[i][j+1])); for(int i=R;i>=1;i--) for(int j=1;j<=C;j++) Dl[i][j]=max(Dl[i][j],max(Dl[i+1][j],Dl[i][j-1])); for(int i=R;i>=1;i--) for(int j=C;j>=1;j--) Dr[i][j]=max(Dr[i][j],max(Dr[i+1][j],Dr[i][j+1])); } int ans=0; void Solve(int R,int C,int K) { for(int i=1;i<=R;i++){ for(int j=1;j<=C;j++){ ans=max(ans,Ul[i][C]+Dl[i+1][j]+Dr[i+1][j+1]); ans=max(ans,Ul[i][j]+Ur[i][j+1]+Dr[i+1][1]); ans=max(ans,Ul[i][j]+Dl[i+1][j]+Dr[1][j+1]); ans=max(ans,Ul[R][j]+Ur[i][j+1]+Dr[i+1][j+1]); } } for(int i=2*K;i<R;i++){ int MaxS=0; for(int j=1;j<=C;j++) MaxS=max(MaxS,sum(i,j,K)); ans=max(ans,Ul[i-K][C]+MaxS+Dr[i+1][1]); } for(int j=2*K;j<C;j++){ int MaxS=0; for(int i=1;i<=R;i++) MaxS=max(MaxS,sum(i,j,K)); ans=max(ans,Ul[R][j-K]+MaxS+Dr[1][j+1]); } } int main() { #ifndef ONLINE_JUDGE freopen("oil.in","r",stdin); freopen("oil.out","w",stdout); #endif int R,C,K; scanf("%d%d%d",&R,&C,&K); for(int i=1;i<=R;i++) for(int j=1;j<=C;j++){ scanf("%d",&a[i][j]); a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1]; } Pre_Solve(R,C,K); Solve(R,C,K); printf("%d\n",ans); }
相关文章推荐
- Hadoop是怎么分块的?
- C++ stringstream 的用法以及getline的用法
- jspSmartUpload组件上传下载
- 回调例子
- jquery实现二级联动,实时查询数据库
- Android进程间通信(IPC)机制Binder简要介绍和学习plan
- Markdown语法和LaTeX数学记号速查手册
- Codeforces Round #343 (Div. 2) -A. Far Relative’s Birthday Cake(组合+模拟)
- iOS国际化
- Java中的基本类型描述及范围
- 在线查看、下载kernel、Android源码的网站
- 通过继承Thread实现多继承和通过实现Runnable接口实现多线程的比较
- Intent传递数据
- c++第一次实验-2
- ArcGIS4Android 3 :最快Android模拟器Genymotion
- php 编程笔记分享
- 一个action读取另一个action里的session
- 初学Java感想
- 集群与负载均衡技术学习笔记一 负载均衡策略
- 基于注解的Spring AOP的配置和使用--转载