【HihoCoder - 1502】最大子矩阵(二维前缀和,尺取)
生活随笔
收集整理的這篇文章主要介紹了
【HihoCoder - 1502】最大子矩阵(二维前缀和,尺取)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題干:
給定一個NxM的矩陣A和一個整數K,小Hi希望你能求出其中最大(元素數目最多)的子矩陣,并且該子矩陣中所有元素的和不超過K。
Input
第一行包含三個整數N、M和K。
以下N行每行包含M個整數,表示A。
對于40%的數據,1 <= N, M <= 10 ?
對于100%的數據,1 <= N, M <= 250 1 <= K <= 2147483647 1 <= Aij?<= 10000
Output
滿足條件最大的子矩陣所包含的元素數目。如果沒有子矩陣滿足條件,輸出-1。
Sample Input
3 3 9 1 2 3 2 3 4 3 4 5Sample Output
4解題報告:
先預處理一個前綴和,然后枚舉每兩行,然后行內尺取就行了,總復雜度N^3,。可以尺取的前提是元素都是正數。
AC代碼:
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define F first #define S second #define ll long long #define pb push_back #define pm make_pair using namespace std; typedef pair<int,int> PII; int n,m,k; ll a[255][255],sum[255][255]; int main() {cin>>n>>m>>k;for(int i = 1; i<=n; i++) {for(int j = 1; j<=m; j++) {scanf("%lld",&a[i][j]);}}for(int i = 1; i<=n; i++) {for(int j = 1; j<=m; j++) {sum[i][j] = a[i][j] + sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1]; }}int ans = -1;for(int i = 1; i<=n; i++) {for(int j = i; j<=n; j++) {int l = 1,r = 1;ll tmp = 0;while(r <= m) {tmp += sum[j][r] - sum[j][r-1] - sum[i-1][r] + sum[i-1][r-1];while(l<=r && tmp > k) {tmp -= sum[j][l] - sum[j][l-1] - sum[i-1][l] + sum[i-1][l-1];l++;}if(tmp <= k)ans = max(ans,(j-i+1)*(r-l+1)); r++;}}}if(ans <= 0) printf("-1\n");else printf("%d\n",ans);return 0 ; }?
總結
以上是生活随笔為你收集整理的【HihoCoder - 1502】最大子矩阵(二维前缀和,尺取)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 信用卡申请后不激活有没有影响 不良影响或
- 下一篇: 【牛客 - 370B】Rinne Lov