BZOJ3594 树状数组优化DP

来源:互联网 发布:沙巴阳光酒店网络 编辑:程序博客网 时间:2024/05/24 13:28

[i,n]
直接上转移方程
f[i][j]ij
f[i][j]=max{f[k][l]|k<i,lj,a[k]+la[i]+j}+1
这样的转移我们可以用二位树状数组来维护区间最大值

#include<bits/stdc++.h>#define bug(x) cout<<(#x)<<" "<<(x)<<endl#define ll long long#define lowbit(x) (x&(-x))using namespace std;const int N=1e4+5;inline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}int n,k,ans;int a[N],t[505][5505];void add(int x,int y,int zjq){    for(int i=x;i<505;i+=lowbit(i))        for(int j=y;j<5505;j+=lowbit(j))             t[i][j]=max(t[i][j],zjq);}int get(int x,int y){    int zjq=0;    for(int i=x;i;i-=lowbit(i))        for(int j=y;j;j-=lowbit(j))             zjq=max(t[i][j],zjq);    return zjq;}int main(){#ifdef Devil_Gary    freopen("in.txt","r",stdin);#endif    n=read(),k=read()+1;    for(int i=1;i<=n;i++) a[i]=read();    for(int i=1;i<=n;i++){        for(int j=k;j>=1;j--){            int zjq=get(j,a[i]+j)+1;            ans=max(ans,zjq);            add(j,a[i]+j,zjq);        }    }    cout<<ans<<endl;}
阅读全文
1 0