【CodeForces - 1060C】Maximum Subrectangle (思维,预处理前缀和,dp,枚举长度)
題干:
You are given two arrays?aa?and?bb?of positive integers, with length?nn?and?mmrespectively.
Let?cc?be an?n×mn×m?matrix, where?ci,j=ai?bjci,j=ai?bj.
You need to find a subrectangle of the matrix?cc?such that the sum of its elements is at most?xx, and its area (the total number of elements) is the largest possible.
Formally, you need to find the largest number?ss?such that it is possible to choose integers?x1,x2,y1,y2x1,x2,y1,y2?subject to?1≤x1≤x2≤n1≤x1≤x2≤n,?1≤y1≤y2≤m1≤y1≤y2≤m,?(x2?x1+1)×(y2?y1+1)=s(x2?x1+1)×(y2?y1+1)=s, and
∑i=x1x2∑j=y1y2ci,j≤x.∑i=x1x2∑j=y1y2ci,j≤x.
Input
The first line contains two integers?nn?and?mm?(1≤n,m≤20001≤n,m≤2000).
The second line contains?nn?integers?a1,a2,…,ana1,a2,…,an?(1≤ai≤20001≤ai≤2000).
The third line contains?mm?integers?b1,b2,…,bmb1,b2,…,bm?(1≤bi≤20001≤bi≤2000).
The fourth line contains a single integer?xx?(1≤x≤2?1091≤x≤2?109).
Output
If it is possible to choose four integers?x1,x2,y1,y2x1,x2,y1,y2?such that?1≤x1≤x2≤n1≤x1≤x2≤n,?1≤y1≤y2≤m1≤y1≤y2≤m, and?∑x2i=x1∑y2j=y1ci,j≤x∑i=x1x2∑j=y1y2ci,j≤x, output the largest value of?(x2?x1+1)×(y2?y1+1)(x2?x1+1)×(y2?y1+1)?among all such quadruplets, otherwise output?00.
Examples
Input
3 3 1 2 3 1 2 3 9Output
4Input
5 1 5 4 2 4 5 2 5Output
1Note
Matrix from the first sample and the chosen subrectangle (of blue color):
Matrix from the second sample and the chosen subrectangle (of blue color):
題目大意:
? ? ?給出兩個數組A和B,他們能組成一個矩陣,然后求子矩陣的和<=X的,最大的子矩陣的面積。
?
解題報告:
? ?聽說有人往滑窗問題上想了?
? ? 如果題目規定是正方形就好做了啊,二維前綴和+二分寬度,直接o(nmlog(nm)),如果矩形的話只能帶倆log了。。。沒嘗試過。但應該也不難寫。
? ?想想啊,為什么題目不直接給你一個矩陣,而是給你倆數組讓你自己造矩陣?肯定是因為矩陣只是個幌子,真正要用到的還是那兩個數組。所以我們推公式:
于是我們知道了和x比較的值只與連續子段和有關,且A和B這兩者之間沒關系(只是最后做一下乘法)所以算出每個長度的最小和,最后再o(nm)遍歷一遍維護答案就行了。
AC代碼:
#include<bits/stdc++.h> #define ll long long using namespace std; const ll INF = 0x3f3f3f3f; ll a[2005],b[2005],suma[2005],sumb[2005]; ll dpa[2005],dpb[2005]; ll x,ans; int main() {int n,m;cin>>n>>m;memset(dpa,INF,sizeof dpa);memset(dpb,INF,sizeof dpb);for(int i = 1; i<=n; i++) scanf("%lld",a+i),suma[i] = suma[i-1] + a[i];for(int i = 1; i<=m; i++) scanf("%lld",b+i),sumb[i] = sumb[i-1] + b[i]; scanf("%lld",&x);for(int len = 1; len<=n; len++) {for(int i = 1; i+len-1<=n; i++) {dpa[len] = min(dpa[len],suma[i+len-1] - suma[i-1]);}}for(int len = 1; len<=m; len++) {for(int i = 1; i+len-1<=m; i++) {dpb[len] = min(dpb[len],sumb[i+len-1] - sumb[i-1]);} }for(int i = 1; i<=n; i++) {for(int j = 1; j<=m; j++) {if(dpa[i] * dpb[j] <= x) ans = max(ans,(ll)i*j);}}printf("%lld\n",ans);return 0 ; }?
網絡版AC代碼:(博客鏈接)
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; const int N=2000; ll lA,lB,x; int A[N+5],B[N+5]; struct NODE{ll len,sum; }node[N*N+5]; int cnt_NODE; bool cmp_NODE(NODE A,NODE B){return A.sum<B.sum; } int Solve(ll sum){int l=0,r=cnt_NODE-1;if(node[r].sum<=sum) return r;while(l+1<r){int mid=(l+r)>>1;if(node[mid].sum<=sum) l=mid;else r=mid;}if(node[r].sum<=sum) return r;return l; } int main(){scanf("%d%d",&lA,&lB);for(int i=1;i<=lA;i++)scanf("%d",&A[i]);for(int i=1;i<=lB;i++)scanf("%d",&B[i]);scanf("%d",&x);for(int i=1;i<=lA;i++){ll sum=0;for(int j=i;j<=lA;j++){sum+=A[j];node[cnt_NODE].len=j-i+1;node[cnt_NODE].sum=sum;cnt_NODE++;}}sort(node,node+cnt_NODE,cmp_NODE);for(int i=1;i<cnt_NODE;i++)node[i].len=max(node[i].len,node[i-1].len);ll ans=0;for(int i=1;i<=lB;i++){ll sum=0;for(int j=i;j<=lB;j++){sum+=B[j];if(x/sum==0) continue;int res=Solve(x/sum);if(node[res].sum>x/sum) continue;ans=max(ans,node[res].len*(j-i+1));}}printf("%lld\n",ans);return 0; }?
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的【CodeForces - 1060C】Maximum Subrectangle (思维,预处理前缀和,dp,枚举长度)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: newsupd.exe - newsup
- 下一篇: 全系徕卡!雷军晒小米12S Pro高清图