题目链接:http://noi.openjudge.cn/ch0206/1768/
可能是数据修改了吧,O(n6)过不了了。
主要是在求一个矩阵的和时,重复计算了很多次。
矩阵首先压缩一下。在输入的时候,就计算好每一列的和于a[i][j]中。
dp:
枚举上界(第一重循环),枚举下界(第二重循环),枚举列数(第三重循环),总的时间复杂度为O(n3);
怎么得到这一列的和呢? 就是利用预处理的 a 数组。temp= a[j][k] - a[i-1][k];
然后这一列上的 dp 方程 f[k] = max(f[k-1]+temp,temp); //选还是不选这一列;
temp2 = max(f[k]) 是这一列的最优值。循环完后,就是 ans = max(temp2) 只一个区间的最优值了。
/* #include<iostream> using namespace std; #define INF 0x3f3f3f3f const int Maxn = 110; int a[Maxn][Maxn]; int main() { int n; cin>>n; for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) cin>>a[i][j]; int ans = -INF; int sum = 0; for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { for(int r=i; r<=n; r++) { for(int c=j; c<=n; c++) { sum = 0; for(int k=i;k<=r;k++) { for(int t=j;t<=c;t++) { sum +=a[k][t]; } } if(sum>ans) ans = sum; } } } } cout<<ans<<endl; return 0; } */ #include <bits/stdc++.h> using namespace std; const int INF = 0x3f3f3f3f; const int Maxn = 110; int a[Maxn][Maxn]; int f[Maxn]; int n; int main() { int ans = -INF; scanf("%d",&n); for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) { scanf("%d",&a[i][j]); a[i][j] +=a[i-1][j]; } for(int i=1; i<=n; i++) { for(int j=i; j<=n; j++) { memset(f,0,sizeof(f)); int temp1 = -INF; for(int k=1; k<=n; k++) { int temp2 = a[j][k] - a[i-1][k]; f[k] = max(f[k-1]+temp2,temp2); temp1 = max(temp1,f[k]); } ans = max(ans,temp1); } } printf("%d ",ans); return 0; }