洛谷P1719 最大加权矩形 (DP/二维前缀和)

题目描述也没啥好说的,就是给你个你n*n的矩形(带权),求其中最大权值的子矩阵。

首先比较好想的就是二维前缀和,n<=120,所以可以用暴力。

复制代码
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,f[130][130],ans=-0x3f3f3f3f;
 4 //n^4爆搜 
 5 int main(){
 6     scanf("%d",&n);
 7     for(int i=1;i<=n;i++)    
 8         for(int j=1;j<=n;j++){
 9             int x;
10             scanf("%d",&x);
11             f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1]+x;
12         }
13     for(int i=1;i<=n;i++)
14         for(int k1=1;k1<=i;k1++)
15             for(int j=1;j<=n;j++)
16                 for(int k2=1;k2<=j;k2++){
17                     int sum=f[i][j]-f[i-k1][j]-f[i][j-k2]+f[i-k1][j-k2];
18                     ans=max(ans,sum);
19                 }
20     cout<<ans;        
21 }
复制代码

当然有更优的解法,我们可以类比P1115最大子段和,把矩形从二维压缩到一维,然后DP,统计答案就行了。

复制代码
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=150;
 4 int n,m,a[N][N];
 5 int temp[N],dp[N],ans=-0x3f3f3f3f;
 6 
 7 void getsum(){
 8     memset(dp,0,sizeof(dp));
 9     for(int i=1;i<=n;i++){//类似于求一维的最大子段和 
10         dp[i]=max(dp[i],dp[i-1]+temp[i]);
11         ans=max(ans,dp[i]);
12     }
13 }
14 
15 void solve(){
16     for(int i=1;i<=n;i++){//矩阵压缩 
17         memset(temp,0,sizeof(temp));
18         for(int j=i;j<=n;j++){
19             for(int k=1;k<=n;k++){
20                 temp[k]+=a[j][k];
21             }
22             getsum();
23         }
24     }
25 }
26 
27 int main(){
28     scanf("%d",&n);
29     for(int i=1;i<=n;i++)
30         for(int j=1;j<=n;j++)
31             scanf("%d",&a[i][j]);
32     solve();
33     cout<<ans;
34 }
复制代码

 



如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
posted @   YHXo  阅读(264)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示