链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目描述
You are given a matrix A of n rows and m columns, containing only integers.
For each row i, choose a non-empty interval li,ri, such that the adjacent row's interval intersects, and maximize the sum of all integers over all intervals.
Formally, choose li,ri such that 1≤li≤ri≤m, max(li,li+1)≤min(ri,ri+1) for all i∈Z∩[1,n), and maximize
输入描述:
The first line contains one integer T (1≤T≤), representing the number of test cases. For each test case, the first line contains two integers n,m (1≤n⋅m≤), representing the size of the matrix. The following nnn lines, each contain mmm integers Ai,j (−≤Ai,j≤), representing each element of the matrix. It is guaranteed that ∑n⋅m≤106.
输出描述:
For each test case, output one line containing a single integer, representing the answer.
示例1
输入
5 4 4 -1 1 1 -1 1 1 -1 -1 -1 1 1 -1 -1 -1 1 1 3 4 2 -3 4 -1 1 2 -4 -7 1 1 -7 2 4 3 1 -1 1 -2 4 5 2 -3 2 6 -5 7 1 1 1 2 2 -1 -1 -1 -2
输出
8 8 20 1 -2
思路:每行用一个pre数组来记录 pre[ j ] = max ( { pre [ j - 1 ] + a [ j ] , 0 , a [ j ] } ),用一个next数组来记录 next [ j ] = max ( { next [ j + 1 ] + a [ j ] , 0 , a [ j ] } ),用数组 v 来更新 dp 数组 ,然后将数组 v 赋值给 dp 数组,最后输出 dp 数组中的 最大值。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
signed main()
{
IOS
int t;
cin >> t;
while(t--){
int n,m;
cin >> n >> m;
vector<int> dp(m+1);
for(int i=1;i<=n;i++){
vector<int> a(m+1),v(m+1,-1e18),pre(m+1),next(m+2);
for(int j=1;j<=m;j++){
cin >> a[j];
pre[j]=max({pre[j-1]+a[j],(int)0,a[j]});//记录当前这个下标的最大值(从前往后推)
}
for(int j=m;j>=1;j--){
next[j]=max({next[j+1]+a[j],(int)0,a[j]});//记录当前这个下标的最大值(从后往前推)
}
int maxn=-1e18;
for(int j=1;j<=m;j++){//从前往后记录maxn和数组v的最大值
maxn=max(maxn+a[j],pre[j-1]+a[j]+dp[j]);
v[j]=max(v[j],maxn+next[j+1]);
}
maxn=-1e18;
for(int j=m;j>=1;j--){//从后往前记录maxn和数组v的最大值
maxn=max(maxn+a[j],next[j+1]+a[j]+dp[j]);
v[j]=max(v[j],maxn+pre[j-1]);
}
dp.swap(v);//更新dp数组
}
cout << *max_element(dp.begin(),dp.end()) << endl;//取dp数组中的最大值
}
return 0;
}