2括號子串行 - a(10分)
題目內容:
一段括號序列被稱為平衡的,如果對於任意字首,左括號的數目都不小於右括號。
給定一段括號序列,問有多少括號子串行是平衡的。(內容相同但位置不同的算兩種。)
輸入格式:
多組測試資料,每組測試資料報含一行乙個括號序列,括號序列的長度 <= 100。
輸出格式:
輸出一行表示答案模 10^9 + 7 後的結果。
輸入樣例:
(()())
()()
輸出樣例:
18 4
hint:
樣例一:
()__
(_)_
(__)
()__
(_)_
(__)
_()_
_(_)
()()
()()
()()
()()
((__))
(())
(()__)
(__())
(())
時間限制:2000ms記憶體限制:128000kb
做了這道題感覺自己對動態規劃根本就不了解,先是想了乙個時間複雜度為2^n的方法,通過記錄每左括號後面的有括號個數,計算求解。
思路與**結果都有問題,時間也超了。
問大四學長的思路:
定義dp[i][j][k]
表示當前我要處理字串中第i個字元,
並且前面已經取了j個左括號和k個右括號。
由於題意要滿足任意字首,左括號的數目都不小於右括號
所以這裡限定j>=k。
最終答案就是把所有dp[n][i][i]累加起來,這裡i代表左括號個數
初始狀態dp[0][0][0]=1,表示空串。
那麼當前處理第i個字元
一種是忽略這個字元,dp[i+1][j][k] += dp[i][j][k]
一種是選擇這個字元,那麼就要判斷這個字元是左還是右。
如果是左,直接累加,dp[i+1][j+1][k] += dp[i][j][k]
否則要先看如果加了這個右括號,會不會違反j>=k的規則,不違反則dp[i+1][j][k+1] += dp[i][j][k],違反就不管了
自己想了一下,大概有點明白。但第二天仔細研究,用遞迴做的話,時間複雜度也是2^n。
遞迴方程是 t(n) = 2*t(n-1) + o1;
用公式沒求明白,但展開看的話還是很明顯的
t(n) = 2 * t(n-1) + o1
= 2^2 * t(n-2) + ( 2 + 1) * o1
…….
= 2^(n-1)t(1) + (2^(n-2) + ……+ 2 + 1) o1 = o2^n
後來發現用迴圈來做時間複雜度僅為n^3。
**如下:
int mo = 1000000007;
long a[101][101][101];
void jisuan(char*p, int n)
else
if (j > k)}}
}}//要注意這次是多組輸入,對於每次輸入要重新初始化。
void chushihua(int n)}}
a[0][0][0] = 1;
}
最終結果就是所有a[n][i][i]的和,n為字元個數,i從1到n/2。因為n個字元,平衡的子串行字元數小於等於n,其中左括號右括號相等,所以i<=n/2即可。 動態規劃入門篇
動態規劃相信大家都知道,動態規劃演算法也是新手在剛接觸演算法設計時很苦惱的問題,有時候覺得難以理解,但是真正理解之後,就會覺得動態規劃其實並沒有想象中那麼難。在上面的數字三角形中尋找一條從頂部到底邊的路徑,使得路徑上所經過的數字之和最大。路徑上的每一步都只能往左下或 右下走。只需要求出這個最大和即可...
演算法設計與分析入門篇 分治作業 1
題目內容 給定 n 個數組成的陣列,求其逆序對的總數。逆序對定義為,存在 i,j 滿足 i j 且 a i a j 的二元組的數目。輸入格式 第一行包含乙個整數,表示陣列的項數。接下來的一行,包含 n 個數 leq 100000 依次表示 ai ai 109 輸出格式 輸出一行表示對應的答案。輸入樣...
演算法設計與分析入門篇 貪心法3
課程排程 題目內容 有 n 個人,要完成 2 門課程。其中第 i 個人學習一門課程所需要的時間是 ti。每個人同一時刻只能修一門課程,每門課程同一時刻只能被乙個人修,中間不能中斷。問所有人都修完 2 門課程,至少需要多少時間。輸入格式 輸入的第一行包含乙個整數 n 1 n 1000000 接下來的一...