ZOJ4027 Sequence Swapping (dp)

dp问题的状态设计都是十分巧妙,根据y总的说法,可以把他看作集合,对于转移,考虑最后一个不同量/

对于dp状态,首先要观察题目的信息,看他有什么,我认为所有的dp的状态都能从题目中猜出来,这题目告诉你括号可以移动。

我们进一步发现,左括号只能与右括号相换,所以所有左括号的相对顺序是不变的,同理右括号也是所以我们可以想到根据这个性质设计状态。

再观察本题的数据范围,1000,说明可能要开二维数组。这样符合题目的数据,当然每道题都不一定一样,但是出题人不可能乱出数据

所以这道题由此可以推断大概率是二维dp,复杂度是N^2,这就能满足条件。对于线性dp的第一维,一般都是前i个某值,或者第i个某值。所以主要是对第二维状态的分析

题目的信息不多,我们要求取的答案是价值的最大,并且这题不是可行性问题,所以我们自然考虑按照常理把价值作为dp数组需要表示的量而不是第二维

那么剩下只有括号移动这一个性质。并且dp题目要考虑到无后效性,所以本题的难点就是想到同一类括号的相对顺序是不变的。所以设计状态为

第i个左括号移动到j这个位置及以后能得到最大的价值是多少,(前i个是倒着数的,因为右边左括号的位置决定了左边左括号的移动范围)。为什么要设计成j以后呢,因为这样方便转移

所以方程就是 f[i][j]=max(f[i+1][j+1]+v,f[i][j+1]),所以dp方程的定义都要做到不会漏掉状态,我们这个方程的意思是,可以从第i个移到j+1以后,和第i+1个移到j+1以后+i个移到这个位置的最大值转移过来。

这样就包含了所有状态。最后的答案自然是f[cnt[1]][1]表示的是最后一个左括号移到第一个位置及后面。这肯定是答案,cnt表示的是倒序的左括号的数量

#include<iostream>
#include<cstring>
#include<cstdio>
#include<map>
#include<algorithm>
#include<queue>
#define ull unsigned long long
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int N=5e5+10;
ll f[1010][1010];
ll sum[N],b[N];
ll a[N];
int p[N];
int cnt[N];
int main(){
    int i;
    int t;
    cin>>t;
    while(t--){
        int n;
        string s;
        cin>>n;
        cin>>s;
        s=" "+s;
        for(i=1;i<=n;i++){
            cin>>a[i];
        }
        cnt[n+1]=0;
        sum[0]=0;
        int tot=0;
        memset(f,0,sizeof f);
        for(i=n;i>=1;i--){
            cnt[i]=cnt[i+1]+(s[i]=='('?1:0);
            if(s[i]==')'){
                sum[tot+1]=sum[tot]+a[i];
                tot++;
            }
            else{
                p[i]=tot;
            }
        }
        ll ans=0;
        for(i=n;i>=1;i--){
            if(s[i]==')')
                continue;
            int j;
            for(j=n-cnt[i]+1;j>=i;j--){
                f[cnt[i]][j]=f[cnt[i]-1][j+1]+a[i]*(sum[p[i]]-sum[n-j+1-cnt[i]]);
            }
            for(j=n-cnt[i];j>=1;j--){
                f[cnt[i]][j]=max(f[cnt[i]][j],f[cnt[i]][j+1]);
            }

        }
        ans=f[cnt[1]][1];
        cout<<ans<<endl;
    }
}
View Code
 
原文地址:https://www.cnblogs.com/ctyakwf/p/12625100.html