【牛客 - 188D 】愤怒(01滚动数组优化dp,括号匹配方案个数,tricks)
生活随笔
收集整理的這篇文章主要介紹了
【牛客 - 188D 】愤怒(01滚动数组优化dp,括号匹配方案个数,tricks)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題干:
小w很生氣
小w有一個長為n的括號序列
憤怒小w想把這個括號序列分為兩個括號序列
小w想讓分為的這兩個括號序列同時合法
小w想知道一共有多少種劃分方案
(劃分的意思是劃分為兩個子序列)
注意兩個序列是 A,B 和 兩個序列是B,A 算兩種方案,也就是同一位置位于不同劃分為方案不同
輸入描述:
第一行一正整數(shù)n 第二行,一串長為n的括號序列輸出描述:
一個正整數(shù) 表示對方案數(shù)對2333取mod后的方案數(shù)示例1
輸入
復(fù)制
4 (())輸出
復(fù)制
6示例2
輸入
復(fù)制
8 ()()()()輸出
復(fù)制
16備注:
n ≤ 10000解題報告:
就是求括號匹配個數(shù)。dp[i][j]表示,長度為i的表達式,左括號比右括號多j個的情況數(shù)。那么ans=dp[len][0]。注意第二層循環(huán)要遍歷到sum[i]!!不能直接跑到10000,這樣也就意味著,比如可以從非法的dp[i][500],加上500個),從而更新到了f[j][0]?
AC代碼:
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #include<cctype> #define ll long long #define pb push_back #define pm make_pair using namespace std; const int MAX = 2e5 + 5; char s[MAX]; int dp[10005][10005];//dp[i][j]代表前i個序列中,左括號比有括號多j個 的方案數(shù)。 const int mod = 2333; int sum[10009]; int main() {int n;cin>>n;scanf("%s",s+1);int len = strlen(s+1);dp[0][0]=1;for(int j = 1; j<=n; j++) {if(s[j]=='(')sum[j]=sum[j-1]+1;else sum[j]=sum[j-1]-1;}for(int i = 1; i<=len; i++) {for(int j = 0; j<=sum[i]; j++) {//不選dp[i][j] = dp[i-1][j];//選if(s[i] == '(' && j>0) dp[i][j] += dp[i-1][j-1];if(s[i] == ')') dp[i][j] += dp[i-1][j+1];dp[i][j]%=mod;}}printf("%d\n",dp[len][0]);return 0 ; }滾動數(shù)組優(yōu)化:
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #include<cctype> #define ll long long #define pb push_back #define pm make_pair using namespace std; const int MAX = 2e5 + 5; char s[MAX]; int dp[2][10005];//dp[i][j]代表前i個序列中,左括號比有括號多j個 的方案數(shù)。 int qq[100000000]; const int mod = 2333; int sum[10009]; int main() {int n;cin>>n;scanf("%s",s+1);int len = strlen(s+1);dp[0][0]=1;for(int j = 1; j<=n; j++) {if(s[j]=='(')sum[j]=sum[j-1]+1;else sum[j]=sum[j-1]-1;}int flag = 0;for(int i = 1; i<=len; i++) {flag ^= 1;for(int j = 0; j<=sum[i]; j++) {//不選dp[flag][j] = dp[flag^1][j];//選if(s[i] == '(' && j>0) dp[flag][j] += dp[flag^1][j-1];if(s[i] == ')') dp[flag][j] += dp[flag^1][j+1];dp[flag][j]%=mod;}memset(dp[flag^1],0,sizeof dp[flag^1]);}printf("%d\n",dp[flag][0]);return 0 ; }注意別忘每次循環(huán)完了之后都memset一下!
總結(jié)
以上是生活随笔為你收集整理的【牛客 - 188D 】愤怒(01滚动数组优化dp,括号匹配方案个数,tricks)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 建行信用卡审核需要多久时间 建行信用卡审
- 下一篇: 最近可转债接连破发,想赚钱掌握两个方法