括號序列與豬豬俠又大戰了起來。
眾所周知,括號序列是乙個只有(和)組成的序列,我們稱乙個括號
序列s合法,當且僅當:
1.( )是乙個合法的括號序列。
2.若a是合法的括號序列,則(a)是合法的括號序列。
3.若a,b是合法的括號序列,則ab是合法的括號序列。
我們考慮match[i]表示從左往右數第i個左括號所對應的是第幾個右
括號,現在他得到了乙個長度為2n的括號序列,給了你m個資訊,第i
個資訊形如ai,bi,表示match[ai]
第一行乙個正整數t,t< = 5,表示資料組數。
對於每組資料,第一行乙個n,m,n表示有幾個左括號,m表示資訊數。
接下來m行,每行兩個數ai,bi,1< = ai,bi< = n。
對於每組資料,輸出乙個數表示答案。
5
1 05 0
3 21 2
2 33 2
2 12 3
3 31 2
2 33 1
1421
20
對於前兩個點,是卡特蘭數的情況。
對於第三個點,合法的情況只可能是 ()()()。
對於第四個點,合法情況可能是 (()()) 或者 (())()
對於第五個點,由於拓撲關係形成了環,顯然無解。
對於 100% 的資料,保證 n < = 300
ydc給我們的考試題…t1…………
ydc:這道題是本場考試最水的
具體做法是區間dp,狀態轉移方程也挺好寫,三種情況:()ab,(ab),(a)b。
重點在如何處理【i的右括號必須在j的右括號左邊】這個約束。
二維字首和。sum[i][j]為1表示i必須在j之前。考慮乙個矩形所代表的含義:
先考慮邊長為1的矩形。矩形((a,b),(a,c))的權值若是1,則表示a必須在b~c中某個的前面。若為0,則表示a沒必要在b~c的任意乙個數左邊,也就是a的右括號可以放c後面或者b前面。
我們發現矩形權值為0的性質可以利用。考慮((a,b),(c,d))的含義:若權值為0,則表示a~c中任意乙個元素對於b~d中任意乙個元素都沒有條件約束。這個性質可以快速查詢乙個括號序列是否可以在另乙個括號序列之前。
狀態dp[i][j]表示第i個左括號到第j個左括號組成的括號序列方案數,然後根據二維字首和查詢dp就行了…
#include
#include
#include
#include
using
namespace
std;
typedef
long
long ll;
const
int sz = 500;
const
int mod = 998244353;
int dp[sz][sz];
int sum[sz][sz];
int getsum(int a,int b,int c,int d)
int ask(int n)
}return dp[1][n];
}void init()
int main()
for(int i = 1;i <= n;i ++)
for(int j = 1;j <= n;j ++)
sum[i][j] += sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];
printf("%d\n",ask(n));
}return
0;}
BZOJ4350 括號序列再戰豬豬俠
括號序列與豬豬俠又大戰了起來。眾所周知,括號序列是乙個只有 和 組成的序列,我們稱乙個括號 序列s合法,當且僅當 1.是乙個合法的括號序列。2.若a是合法的括號序列,則 a 是合法的括號序列。3.若a,b是合法的括號序列,則ab是合法的括號序列。我們考慮match i 表示從左往右數第i個左括號所對...
bzoj4350 括號序列再戰豬豬俠
括號序列與豬豬俠又大戰了起來。眾所周知,括號序列是乙個只有 和 組成的序列,我們稱乙個括號 序列s合法,當且僅當 1.是乙個合法的括號序列。2.若a是合法的括號序列,則 a 是合法的括號序列。3.若a,b是合法的括號序列,則ab是合法的括號序列。我們考慮match i 表示從左往右數第i個左括號所對...
BZOJ4350 括號序列再戰豬豬俠 區間DP
括號序列與豬豬俠又大戰了起來。眾所周知,括號序列是乙個只有 和 組成的序列,我們稱乙個括號序列s合法,當且僅當 1.是乙個合法的括號序列。2.若a是合法的括號序列,則 a 是合法的括號序列。3.若a,b是合法的括號序列,則ab是合法的括號序列。我們考慮match i 表示從左往右數第i個左括號所對應...