sakura、 @ 2022-04-02 22:44:07
我是用二维前缀和做的,主要就是先求出二维前缀和中最大的一个,并记录他的下标,然后根据这个下标来求得最大和 代码如下
package qianzhui;
/*
* https://www.luogu.com.cn/problem/P1719
* */
import java.util.Scanner;
public class zuidajvxing {
static int n;
static int[][] nums = new int[121][121];
static int[][] sum = new int[121][121];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
nums[i][j] = sc.nextInt();
}
}
int x2 = 0, y2 = 0;
int max = Integer.MIN_VALUE;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
sum[i][j] = nums[i][j] + sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1];
if (sum[i][j] > max) {
max = sum[i][j];
x2 = i;
y2 = j;
}
}
}//得到二维前缀和数组中最大的,以及他的下标
int res = Integer.MIN_VALUE;
for (int i = 1; i <= x2; i++) {
for (int j = 1; j <= y2; j++) {
int num = getSum(i, j, x2, y2);
if (num > res) {
res = num;
}
}
}//因为要围成矩形,所以下标限制在x2和y2之间
System.out.println(res);
}
static int getSum(int x1, int y1, int x2, int y2) {
int res = sum[x2][y2] - sum[x2][y1-1] - sum[x1-1][y2] + sum[x1-1][y1-1];
return res;
}//得到x1 y1到x2 y2之间的和
}
by sakura、 @ 2022-04-02 22:44:57
还想问个问题,洛谷的测试数据到底怎么下载啊,看描述说要实名,实名是只要绑定手机号就可以了吗,每次点了之后都说我今日下载次数到达上限了
by Dreamer_002 @ 2022-07-22 11:29:37
请问你是用Python做的吗?
by limoalin @ 2022-08-16 20:17:17
@sakura
最大加权矩形不一定在最大前缀和里吧
(洛谷数据实名就可下载,未实名点击会显示到达上限)
by limoalin @ 2022-08-16 20:17:58
实名就是身份验证
by flybirdyujunze @ 2023-08-09 14:42:25
#include <bits/stdc++.h>
#pragma GCC opimize("O2")
using namespace std;
int n,i,ma,j,a1,b1,s,a2,b2,a[1001][1001],b[1001][1001],c[1001][1001];
int main(){
ios::sync_with_stdio(0);
cin.tie(NULL);cout.tie(NULL);
cin>>n;ma=-2e9;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
cin>>a[i][j];
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
b[i][j]=b[i][j-1]+a[i][j];
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
c[i][j]=c[i-1][j]+b[i][j];
for(a1=1;a1<=n;a1++)
for(b1=1;b1<=n;b1++)
for(a2=a1;a2<=n;a2++)
for(b2=b1;b2<=n;b2++){
s=c[a2][b2]-c[a1-1][b2]-c[a2][b1-1]+c[a1-1][b1-1];
ma=max(ma,s);
}
cout<<ma;
}