1. 程式人生 > >2018 浙江省大學生程式設計競賽 D.Sequence Swapping(動態規劃dp,思維邏輯)

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;
}