zjnu(1183)——括弧序列【基礎演算法・動態規劃】——進階__動態規劃

來源:互聯網
上載者:User

首先,我只想聲明一點,這道題有毒。。。我用char讀入就錯了,然而換成string讀入就對了或者可以把定義char的數組開的大一點,原先1A的一題硬是糾結了老半天。

傳送門:zjnu

題意:

就是對於一個組成的序列,添加盡量少的括弧得到一個規則序列,並且輸出這個序列的長度。

不過我學到了兩種定義dp狀態的方法:

1)定義dp[i][j]為i~j中需要添加的最少的括弧數。這裡我們記錄s為一段字元的開始位置,e為一段字元的結束位置。

     ①當(a[s]=='('&&a[e]==')')||(a[s]=='['&&a[e]==']')時,dp[s][e]=min(dp[s][e],dp[s+1][e-1]); 

     ②當(a[s]=='('&&a[e]!=')')||(a[s]=='['&&a[e]!=']')時,dp[s][e]=min(dp[s][e],dp[s][e-1]+1);

     ③當(a[e]==')'&&a[s]!='(')||(a[e]==']'&&a[s]!='[')時,dp[s][e]=min(dp[s][e],dp[s+1][e]+1);

     ④然後當兩個數中間還有其他數存在的時候,那麼我們就用for,像石子歸併那樣,然後去更新dp[s][e]

最後輸出的時候只要輸出dp[0][len-1]+len就好了。

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>#include<cstring>using namespace std;#define inf 99999999#define maxn 111int main(){string a;cin>>a;int l=a.length();int dp[111][111];for(int i=0;i<l;i++) dp[i][i]=1;for(int len=2;len<=l;len++){for(int s=0;s<=l-len;s++){int e=s+len-1;dp[s][e]=inf;//!!!if((a[s]=='('&&a[e]==')')||(a[s]=='['&&a[e]==']')) dp[s][e]=min(dp[s][e],dp[s+1][e-1]);if((a[s]=='('&&a[e]!=')')||(a[s]=='['&&a[e]!=']')) dp[s][e]=min(dp[s][e],dp[s][e-1]+1);if((a[e]==')'&&a[s]!='(')||(a[e]==']'&&a[s]!='[')) dp[s][e]=min(dp[s][e],dp[s+1][e]+1);for(int k=s;k<e;k++){dp[s][e]=min(dp[s][e],dp[s][k]+dp[k+1][e]);}}}printf("%d\n",dp[0][l-1]+l);}



2)第二種狀態定義的和第一種有點不一樣。

定義dp[i][j]為i~j的區間內符合規範的字串的最短的長度。

當然在這裡我們需要進行初始化,對於不同位置的dp,我們需要進行不同的計算。(這裡初始化是很重要的)

當a[s]=='('&&a[e]==')'時,那麼dp[s][e]=dp[s+1][e-1]+2;

否則的話,則去尋找跳板,然後更新dp[s][e]。

其實主要的思路就是先算出小區間的每個最短的長度,然後再根據小區間然後去更新大區間的值。

最後輸出的直接是dp[0][len-1]就可以了。

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>#include<cstring>using namespace std;#define maxn 111#define inf 99999999int main(){string a;cin>>a;int dp[111][111];int len=a.length();for(int i=0;i<len;i++){for(int j=0;j<len;j++){if(i==j) dp[i][j]=2;if(i>j) dp[i][j]=0;else if(i<j) dp[i][j]=inf;}}for(int l=2;l<=len;l++){for(int s=0;s<=len-l;s++){int e=s+l-1;if((a[s]=='('&&a[e]==')')||(a[s]=='['&&a[e]==']')){if(l>2) dp[s][e]=dp[s+1][e-1]+2;else dp[s][e]=2;}for(int k=s;k<e;k++){dp[s][e]=min(dp[s][e],dp[s][k]+dp[k+1][e]);}}}printf("%d\n",dp[0][len-1]);}

理解。。。舉一反三。。加油。。。


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.