• zoj4027 线性dp!好题


    非常好的dp,可是我太菜做不出来。。

    /*
    第i个左括号不可能越过第i+1个左括号
    如果第i个左括号到位置j,前提是第i+1个左括号就必须到位置j+1即以后 
    用dp[i][j]表示把第i个左括号转移到位置j的最大收益,
        那么dp[i][j]=将i移到j位置的收益+max(dp[i+1][j+1..n])
    这样的复杂度是n^3,一个n的复杂度用来重复计算max(dp[i+1][j+1..n])了 
    那么就额外开一个数组Max[i][j]:第i个括号转移到第j个位置之后的最大收益 
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 1005
    #define INF 0x3f3f3f3f 
    long long val[maxn],dp[maxn][maxn],n,num[maxn],pos[maxn],sum[maxn],t;
    char s[maxn];
    int main(){
        cin>>t;
        while(t--){
            cin>>n;scanf("%s",s+1);
            for(int i=1;i<=n;i++)cin>>val[i];
            int l=0,r=0;//左括号右括号个数 
            for(int i=1;i<=n;i++)
                if(s[i]=='(')
                    pos[++l]=i,num[l]=r;
                else 
                    sum[++r]=sum[r-1]+val[i];
            
            memset(dp,0,sizeof dp);
            for(int i=l;i>=1;i--){//第i个左括号 
                for(int j=n-(l-i);j>=pos[i];j--){
                    long long tmp=val[pos[i]]*(sum[num[i]+j-pos[i]]-sum[num[i]]);
                    dp[i][j]=dp[i+1][j+1]+tmp;
                    if(j<n-(l-i))dp[i][j]=max(dp[i][j],dp[i][j+1]);//把第i个左括号移到位置j及以后的最大收益 
                }
                for(int j=pos[i]-1;j>=pos[i-1];j--)dp[i][j]=dp[i][j+1];
            }
            
            long long ans=0;
            for(int i=1;i<=n;i++)ans=max(ans,dp[1][i]);
            cout<<ans<<endl;
        }
    }
  • 相关阅读:
    非post请求时整个url作为参数传递出现bug
    UML类图及类与类之间的关系
    MyBatis中if,where,set标签
    MySQL主从复制配置遇到的部分问题
    SpringMVC的各种参数绑定方式
    对解释器模式的认识
    大型网站技术架构案例分析
    淘宝网质量属性描述
    阅读架构漫谈笔记
    阅读计划——《软件需求十步走》06
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10720084.html
Copyright © 2020-2023  润新知