原題鏈結
乙個長度為 2n 的括號序列由 n 個左括號和 n 個右括號組成,問有多少種合法方案;
顯然對於任意時刻,要是能找開 b,那麼之前一定有乙個 a 給他提供了一張 50 的 money,如果將 a 看做是乙個左括號,將 b 看做是乙個右括號,那麼這道題就轉化成了:求合法括號序列的方案數
相信對於這種括號序列匹配的問題,大佬一眼就能看出答案就是卡特蘭數,但是我不會qwq 。
由於 xcg 正在練習 dp,所以我們還是用 dp 的方法來優雅的解決這道題吧qwq 。
dp [ i ][ j ][ k ]:當前我們已經有 i 個球迷在排隊了,其中有 j 個是 a,有 k 個是 b;
當然也可以把第一維優化掉,但是空間大真的是可以為所欲為的~
對於乙個長度為 i 的佇列,一定是從乙個長度為 i-1 的佇列插入乙個 a 和 b 得到的;
那麼我們分別加上這兩種情況的方案數即可;
注意時刻保證 a 的數量一定大於 b 的數量;
dp [ i ][ j ][ k ] += dp [ i-1 ][ j-1 ][ k ] + dp [ i-1 ][ j ][ k-1 ]
紅色部分表示是插入了乙個 a 後得到的
藍色部分表示是插入了乙個 b 後得到的
剛開始乙個人也沒有,方案數是 1,即:
dp [ 0 ][ 0 ][ 0 ] = 1
n 個 a 和 n 個 b 都排好了,共有 2n 個人;
ans = dp [ 2n ][ n ][ n ]
code:
#include#includeusing
namespace
std;
intread()
while(ch>='
0'&&ch<='9'
)
return a*x;
}const
int n=50
;int
n;long
long dp[n<<2][n][n]; //
dp[i][j][k]:有i個人在排隊,其中有j個a類的,有k個b類的方案數
//注意到每時每刻a類的都不少於b類的
intmain()
}printf(
"%lld\n
",dp[2*n][n][n]); //
輸出答案
return0;
}
P1754球迷購票問題
這是一道動態規劃題,其實也是個數論題。有n人拿50,有n人拿100買票,必須讓50元的人買,不然無法找零錢,問最多有幾種方案可以每一次都買票成功。這個題首先令人想到搜尋,但是隨即發現dp是正解,於是dp i j 代表當50為i,100為j人時 最大的方案數,於是去推導方程,得到dp i j dp i...
洛谷 P1754 球迷購票問題
盛況空前的足球賽即將舉行。球賽門票售票處排起了球迷購票長龍。按售票處規定,每位購票者限購一張門票,且每張票售價為50元。在排成長龍的球迷中有n個人手持面值50元的錢幣,另有n個人手持面值100元的錢幣。假設售票處在開始售票時沒有零錢。試問這2n個球迷有多少種排隊方式可使售票處不致出現找不出錢的尷尬局...
洛谷P1754 球迷購票問題 題解
卡特蘭數經典 texttt 分拆問題。分析 題意相當於排列 n 個 texttt a 和 n 個 texttt b 使得相鄰 texttt 有序!消掉,然後左右元素並到一起再消,最後消完的序列個數。設 texttt 為乙個組 1 texttt 自巢狀一次為乙個組 2 即 texttt 以此類推。後面...