CF1304F Animal Observation(线段树+dp)

虽然题目说着分两种类型,其实就是相当于对于每一行,选择一个矩形去框

那么这样就统一了形式,而我们发现,每一行只跟上一行相关。

还有一个问题是交叉部分的去重,我们发现这有三种情况,因此对于三种情况分别讨论

但是枚举更新复杂度太高,因此想到优化,这种优化比较套路,用线段树求区间最大值就行

CF1304F Animal Observation(线段树+dp)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int N=1e5+10;
const int mod=1e9+7;
const ll inf=1e12;
int n,m,k;
int a[55][20200];
ll sum[55][20200];
ll f[20200];
struct node{
    int l,r;
    ll mx;
};
struct Tree{
    node tr[N<<2];
    void build(int u,int l,int r){
        if(l==r){
            tr[u]={l,r,-inf};
        }
        else{
            tr[u]={l,r};
            int mid=l+r>>1;
            build(u<<1,l,mid);
            build(u<<1|1,mid+1,r);
            pushup(u);
        }
    }
    void pushup(int u){
        tr[u].mx=max(tr[u<<1].mx,tr[u<<1|1].mx);
    }
    void modify(int u,int l,int r,ll x){
        if(tr[u].l>=l&&tr[u].r<=r){
            tr[u].mx=x;
            return ;
        }
        int mid=tr[u].l+tr[u].r>>1;
        if(l<=mid)
            modify(u<<1,l,r,x);
        if(r>mid)
            modify(u<<1|1,l,r,x);
        pushup(u);
    }
    ll query(int u,int l,int r){
        if(l>r)
            return -1e12;
        if(tr[u].l>=l&&tr[u].r<=r){
            return tr[u].mx;
        }
        int mid=tr[u].l+tr[u].r>>1;
        ll ans=-1e12;
        if(l<=mid)
            ans=max(ans,query(u<<1,l,r));
        if(r>mid)
            ans=max(ans,query(u<<1|1,l,r));
        return ans;
    }
}T[5];
int main(){
    ios::sync_with_stdio(false);
    cin>>n>>m>>k;
    int i,j;
    for(i=1;i<=n;i++){
        for(j=1;j<=m;j++){
            cin>>a[i][j];
            sum[i][j]=sum[i][j-1]+a[i][j];
        }
    }
    T[1].build(1,1,m+10);
    T[2].build(1,1,m+10);
    T[3].build(1,1,m+10);
    for(i=1;i<=n;i++){
        for(j=1;j+k-1<=m;j++){
            f[j]=max(T[3].query(1,1,j-k),T[3].query(1,j+k,m));
            f[j]=max(f[j],T[1].query(1,j-k+1,j)+sum[i][j-1]);
            f[j]=max(f[j],T[2].query(1,j+1,j+k)-sum[i][j+k-1]);
            f[j]=max(f[j],0ll);
        }
        for(j=1;j+k-1<=m;j++){
            f[j]+=(sum[i][j+k-1]-sum[i][j-1]);
            f[j]+=(sum[i+1][j+k-1]-sum[i+1][j-1]);
            T[1].modify(1,j,j,f[j]-sum[i+1][j+k-1]);
            T[2].modify(1,j,j,f[j]+sum[i+1][j-1]);
            T[3].modify(1,j,j,f[j]);
        }
    }
    cout<<T[3].query(1,1,m)<<endl;
    return 0;
}
View Code

 

上一篇:Sarsa-Lambda


下一篇:[CF1304F] Animal Observation - dp,单调队列