2018 浙江省大学生程序设计竞赛 D.Sequence Swapping(动态规划dp,思维逻辑)

转载出处:https://blog.csdn.net/i11000/article/details/80209662

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<stack>
#include<algorithm>
#include<map>
#include<set>
#include<cmath>
#include<map>
#define PI acos(-1)
#define INF 0x3f3f3f3f
#define LL long long
#define MOD 10007
using namespace std;
const int maxn=1e3+5;
LL flag[maxn],a[maxn];
LL dp[maxn],val[maxn];//dp[i]记录它左边的括号能换到这个位置的得分最大值
LL t,n;
string s;
int main()
{
   cin>>t;
   while(t--)
   {
      cin>>n;
      cin>>s;
      for(int i=0;i<s.size();i++)
      {
         if(s[i]=='(')
            flag[i+1]=0;
         else
            flag[i+1]=1;
      }
      for(int i=1;i<=n;i++)
      {
         cin>>val[i];
      }
      memset(dp,0,sizeof(dp));
      LL tempSum,tempVal;
      for(int i=1;i<=n;i++)
      {
         if(flag[i])//如果遇到右括号
         {
            dp[i]=max(dp[i],dp[i-1]);
            continue;
         }
         tempSum=val[i];
         tempVal=dp[i-1]<0?0:dp[i-1];
         dp[i]=tempVal;//当前位置i为左括号时,因为不可能换到左边,所以取tempVal
         for(int j=i+1;j<=n;j++)
         {
            if(flag[j])//如果是右括号
            {
               if(flag[j]==1)
               {
                  flag[j]=2;
                  dp[j]=tempSum*val[j]+tempVal;//更新dp[j]
               }
               else//如果dp[j]之前已经更新过,比较一下取较大值
                  dp[j]=max(dp[j],tempSum*val[j]+tempVal);
               tempVal=dp[j];//每次更新后都需要更新tempVal
            }
            else
               tempSum+=val[j];
         }
      }
      cout <<  dp[n] << endl;
   }

   return 0;
}

猜你喜欢

转载自blog.csdn.net/wwwlps/article/details/83584340
今日推荐