洛谷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 }
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!