POJ 1050(貪心,字首和,區間和)
阿新 • • 發佈:2018-12-15
#include<iostream> #include<cstdio> #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<<x1<<" " <<y1<<" " <<x2<<" " <<y2<<endl; } } } } } 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<iostream> #include<cstdio> #include<cstring> #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; }