ACM题集:https://blog.csdn.net/weixin_39778570/article/details/83187443
链接:http://poj.org/problem?id=1050
题目要求子矩阵的最大和
由于数据比较小,故可以暴力求解
#include
#include
#define ll long long
#define fo(i,j,n) for(register int i=j; i<=n; ++i)
using namespace std;
int a[105][105],n;
int sum[105][105];
// 矩阵前缀和
void init(){
fo(i,1,n){
fo(j,1,n){
sum[i][j] = sum[i-1][j] + sum[i][j-1] + a[i][j] - sum[i-1][j-1];
}
}
}
// 查询矩阵和## 标题
int query(int x1, int y1, int x2, int y2){
return sum[x2][y2] - sum[x1-1][y2] - sum[x2][y1-1] + sum[x1-1][y1-1];
}
void solve(){
int MAX = -1e8;
fo(x1,1,n){
fo(y1,1,n){
fo(x2,x1,n){
fo(y2,y1,n){
int t = query(x1,y1,x2,y2);
if(t>MAX) {
MAX = t;
// cout<
}
}
}
}
}
printf("%d\n",MAX);
}
int main(){
scanf("%d",&n);
fo(i,1,n){
fo(j,1,n){
scanf("%d",&a[i][j]);
}
}
init();
solve();
return 0;
}
贪心解法O(n^3)
优化为
类似一维数组求最大连续序列和
#include
#include
#include
#define ll long long
#define fo(i,j,n) for(register int i=j; i<=n; ++i)
using namespace std;
const int maxn = 1e4;
int mp[maxn][maxn],n;
int d[maxn];
void solve(){
int ans = mp[1][1];
fo(i,1,n){ // i行
memset(d,0,sizeof(d));
fo(j,i,n){ // j行
fo(k,1,n){ // k列
d[k] += mp[j][k]; // d[k] 表示第k列 第i~j行的和(区间和)
}
// 接下来的做法就类似一维数组求最大连续序列和
int sum = 0;
fo(k,1,n){
sum += d[k];
ans = max(ans,sum);
if(sum<0) sum=0;
}
}
}
printf("%d\n", ans);
}
int main(){
while(scanf("%d",&n)==1){ // 使程序更加具有鲁棒性
fo(i,1,n){
fo(j,1,n)
scanf("%d",&mp[i][j]);
}
solve();
}
return 0;
}