luogu 2308新增括號

2022-02-24 16:26:56 字數 1041 閱讀 7548

傳送門現在要添上n-1對括號,加法運算依括號順序進行,得到n-1個中間和,求出使中間和之和最小的添括號方法。

這道題其實是乙個很簡單的區間dp,中間和的意思是括號裡面的和,也就是說,乙個括號就有乙個中間和,然後求總的中間和。

設dp[l][r]表示區間\([l,r]\)內最大中間和是多少,然後dp方程也是乙個很簡單的入門級方程

\[dp[l][r]=min(dp[l][r],dp[l][k]+dp[k+1][r]+sum[r]-sum[l-1])

\]列舉到乙個區間,表示把這個區間兩端加上括號。

然後到了這道題的關鍵部分,怎麼輸出在那個地方新增括號以及每乙個中間和

我們一步一步來說

首先我們用到乙個斷點記錄陣列,記錄區間\([l,r]\)的最優值斷點處

輸出括號新增的序列,輔助陣列lc,rc,然後遞迴改變兩個輔助陣列的值,然後輸出括號序列

輸出每一部分的中間和,因為由小到大,所以也是遞迴輸出。

#include #include #include #include #include using namespace std;

int lc[50],rc[50],sum[50],n,a[50],dp[50][50],cirl[50][50];

void print(int l,int r)

void prinf(int l,int r)

int main()

for(int len=2; len<=n; len++)

for(int l=1,r=len+l-1; r<=n; l++,r++)

for(int k=l; k<=r; k++)

if(dp[l][r]>=dp[l][k]+dp[k+1][r]+sum[r]-sum[l-1])

print(1,n);

for(int i=1; i<=n; i++)

cout << endl;

cout << dp[1][n]

return 0;

}

P2308 新增括號

一看這題 我能ac 看完這題 我要換題 這題第二問其實就是乙個鏈的石子合併,也就是不用處理環 所以一三問怎麼處理?陣列 mid i j 記錄區間 l r 的斷點 陣列 le i 表示 a i 左邊有幾個左括號 陣列 ri i 表示 a i 右邊有幾個右括號 遞迴處理一下括號數 單數字兩邊肯定不能有括...

P2308 新增括號 dfs記錄dp路徑

傳送門 一看肯定是區間dp 因為和和合併石子很相似,都要加n 1次 轉移方程為 其中he i j 是i到j的和 dp i j min dp i j dp i k dp k 1 j he i j 問題 如何輸出括號 在轉移的時候,我們可以用vis i j 來記錄i到j合併的斷點k,所以可以分別遞迴i至...

矩陣鏈乘法,新增括號

給定n個矩陣 a1,a2,an 其中ai與ai 1是可乘的,i 1,2 n 1。如何確定計算矩陣連乘積的計算次序,使得依此次序計算矩陣連乘積需要的數乘次數最少。input 有n個矩陣連乘,用一行有n 1個數陣列表示,表示是n個矩陣的行及第n個矩陣的列,它們之間用空格隔開.output 你的輸出應該有...