hdu 5760 Palindrome Bo DP

来源:互联网 发布:网络监控能看到多久的 编辑:程序博客网 时间:2024/05/16 12:33

可以发现最后一个字母一定是最左最有,那么dp方程很好转移,但是是3方的,如果先减1话,我们想到每次扫到的结果可以重复利用,于是每次维护当前数的第一个位置在哪即可。

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<cmath>using namespace std;const int maxn=5005;const int mod=1000000007;int dp[maxn][maxn];int dp1[maxn][maxn];int a[maxn];int ne[maxn];int pre[maxn];int l1[maxn],r1[maxn];int b[maxn];int main(){    int n;    while (scanf("%d",&n)!=EOF) {        for(int i=1;i<=n;i++){ scanf("%d",&a[i]);            b[i]=a[i];        }        sort(b+1,b+1+n);        for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+1+n,a[i])-b;        memset(l1,0,sizeof(l1));        memset(r1,0,sizeof(r1));        for(int i=1;i<=n;i++){            r1[a[i]]=i;        }        memset(ne,0,sizeof(ne));        for(int i=n;i>=1;i--){            l1[a[i]]=i;        }        for(int i=n;i>=1;i--){            dp[i][i]=1;            dp1[i][i]=1;            int ma=0,su=0;            for(int j=i+1;j<=n;j++){                dp[i][j]=0;                if(a[i]==a[j]){                    dp[i][j]=ma+2;                    if(ma==0) dp1[i][j]=1;                    else dp1[i][j]=su;                }                if(a[j]<=a[i]){                    if(ne[a[j]]==0) ne[a[j]]=j;                    if(ma<dp[ne[a[j]]][j]){                        ma=dp[ne[a[j]]][j];                        su=dp1[ne[a[j]]][j];                    }                    else if(ma==dp[ne[a[j]]][j]){                        if(pre[a[j]]!=0){                            if(dp[ne[a[j]]][pre[a[j]]]==dp[ne[a[j]]][j]){                                su-=dp1[ne[a[j]]][pre[a[j]]];                                su%=mod;                                su+=dp1[ne[a[j]]][j];                                su%=mod;                            }                            else{                                su+=dp1[ne[a[j]]][j];                                su%=mod;                            }                        }                        else{                            su+=dp1[ne[a[j]]][j];                            su%=mod;                        }                    }                    pre[a[j]]=j;                }            }            for(int j=i+1;j<=n;j++){                ne[a[j]]=0;                pre[a[j]]=0;            }        }        int s=0;        for(int i=1;i<=n;i++){            if(l1[i]!=0){                s=max(s,dp[l1[i]][r1[i]]);            }        }        int ans=0;        for(int i=1;i<=n;i++){            if(l1[i]!=0){                if(s==dp[l1[i]][r1[i]]){                    ans+=dp1[l1[i]][r1[i]];                    ans%=mod;                }            }        }        ans=(ans+mod)%mod;        printf("%d %d\n",s,ans);    }}


0 0
原创粉丝点击