好吧,拿一个简单的DP来练练手(捂脸)
看到的第一眼就想到最大连续子区间和的问题,然后想办法往上面靠
我用的不是二维树状数组,而是n个一维的树状数组,通过枚举子矩阵的行数,转化为最大连续子区间和
估计是个n^3lgn的复杂度,算上树状数组的查询的话,因为数据量小,也就过去了。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int arr[110][110],n,bit[110][110],dp[110],ans,te;
void ins(int i,int j);
int get(int col,int top,int bot);
int main(){
ios_base::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
cin>>arr[i][j],ins(i,j);
for(int length=1;length<=n;++length)
for(int i=1,j=i+length-1;j<=n;++i,++j){
for(int k=1;k<=n;++k){
te=get(k,i,j);
dp[k]=max(te,dp[k-1]+te);
ans=max(ans,dp[k]);
}
}
cout<<ans<<endl;
return 0;
}
void ins(int i,int j){
te=i;
while(te<=n)
bit[te][j]+=arr[i][j],te+=te&-te;
}
int get(int col,int top,int bot){
int ans=0;
while(bot)
ans+=bit[bot][col],bot-=bot&-bot;
--top;
while(top)
ans-=bit[top][col],top-=top&-top;
return ans;
}