codeforces 629C Famil Door and Brackets (dp + 枚举)

题目链接:

  codeforces 629C Famil Door and Brackets

题目描述:

  给出完整的括号序列长度n,现在给出一个序列s长度为m。枚举串p,q,使得p+s+q是合法的括号串,长度为n,问p,q的取值数目。

解题思路:

  枚举p的长度,可以直接得到q的长度。因为要满足在任意位置‘(‘ 数目大于 ’)‘ 的数目,所以统计一下s串中 ’(‘ - ‘)‘ 的最小数目minx。dp[i][j] 代表 到位置 i 时,满足 ‘(‘ - ‘)‘ == j 的情况数目。然后枚举p的 j (i > -minx), 然后根据p串推出q串满足合法串的状态,两者相乘。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 typedef __int64 LL;
 5 const int INF = 1e9 + 7;
 6 const int maxn = 100010;
 7 const int N = 2100;
 8 const int mod = 1e9+7;
 9
10
11 ///dp[i][j] 到第i个位置,有j个不平衡(括号
12 LL dp[N][N], n, m;
13 char str[maxn];
14
15 void init ()
16 {
17     int num = 2010;
18     memset (dp, 0, sizeof(dp));
19     dp[0][0] = 1;
20
21     for (int i=1; i<=num; i++)
22         for (int j=0; j<=i; j++)
23         {
24             if (j > 0)
25                 dp[i][j] = (dp[i][j] + dp[i-1][j-1]) % mod;
26             dp[i][j] = (dp[i][j] + dp[i-1][j+1]) % mod;
27         }
28 }
29
30 LL solve ()
31 {
32     int minx = INF, tmp = 0, num = n - m;
33
34     for (int i=0; str[i]; i++)
35     {
36         if (str[i] == ‘(‘)
37             tmp ++;
38         else
39             tmp --;
40         minx = min (minx, tmp);
41     }
42
43     LL ans = 0;
44     for (int i=0; i<=num; i++)
45         for (int j=0; j<=i; j++)
46             if (j >= -minx && num-i >= j + tmp)
47                 ans = (ans + dp[i][j]*dp[num-i][j+tmp]) % mod;
48
49     return ans;
50 }
51
52 int main ()
53 {
54     init ();
55     while (scanf ("%I64d %I64d", &n, &m) != EOF)
56     {
57         scanf ("%s", str);
58         printf ("%I64d\n", solve ());
59     }
60     return 0;
61 }
时间: 2024-10-12 16:32:15

codeforces 629C Famil Door and Brackets (dp + 枚举)的相关文章

CodeForces 629C Famil Door and Brackets

DP.听了同学的讲解才会的. 具体做法:dp[i][j]表示长度为 i 的括号串,前缀和(左括号表示1,右括号表示-1)为 j 的有几种. 状态转移很容易得到:dp[i][j]=dp[i - 1][j + 1]+dp[i - 1][j - 1],表示 i 这位分别放上右括号和左括号. 然后就是要处理题目的问题了: 我们可以枚举P串的长度和P串的前缀和,来看这种情况下是否符合题目要求,如果符合答案增加. 那么如何判断P串长度为left,前缀和为p的情况下,有几种符合题目要求呢? 先对已经存在的那个

CodeForces 21D Traveling Graph 状压dp+欧拉回路

题目链接:点击打开链接 题意: 给定n个点m条边的无向图 求从1点开始经过每条边至少一次最后回到1点的最小路程 显然就是找一条路径可重复的欧拉回路 思路: 首先对于欧拉回路的结论是:所有点的度数都为偶数 因为所有边至少经过一次,那么可以把题意转换成加最少多少条边使得图满足以上结论 而加的边目的是为了把奇度数转成偶度数,先floyd一下得到任意点间加边的最小花费 dp[i]表示状态i下度数都为偶数的最小花费. 状压dp,把i状态下,所有未选择的点中挑2个奇度数的转移即可. #include <cs

[Codeforces 464D]World of Darkraft(期望DP)

[Codeforces 464D]World of Darkraft(期望DP) 题面 游戏中有k种装备,每种装备初始时都是等级1.zyd每打一只怪,就会随机爆出一件装备.掉落和更新装备方式如下: 假设这种装备当前等级为t,那么系统会在[1,t+1]中等概率随机出该装备的等级.爆出装备后,会装备上身上的和爆出的装备之间等级更高的那件,并卖掉等级更低的装备.其中等级为i的装备价格为i金币. 求打了n只怪后获得金币的期望值,精确到\(10^{-9}\). \(n,k\leq 10^5\) 分析 首先

11825 - Hackers&#39; Crackdown 状态压缩 dp 枚举子集

11825 - Hackers' Crackdown 状态压缩 dp 枚举子集 ACM 题目地址:11825 - Hackers' Crackdown 题意: 有一个由编号0~n-1的n台计算机组成的网络,一共有n种服务,每台计算机上都运行着全部服务,对于每台计算机,你可以选择停止一项服务,这个行为会导致与这台计算机和与他相连的其他计算机上的这项服务都停止(原来已经停止的继续保持停止状态).求最多能使多少个服务瘫痪(即没有任何一台计算机在运行这项服务). 分析: 题目说白了,就是: 把n个集合p

UVA 11825 - Hackers&amp;#39; Crackdown 状态压缩 dp 枚举子集

UVA 11825 - Hackers' Crackdown 状态压缩 dp 枚举子集 ACM 题目地址:11825 - Hackers' Crackdown 题意: 有一个由编号0~n-1的n台计算机组成的网络,一共同拥有n种服务,每台计算机上都执行着所有服务,对于每台计算机,你能够选择停止一项服务,这个行为会导致与这台计算机和与他相连的其它计算机上的这项服务都停止(原来已经停止的继续保持停止状态). 求最多能使多少个服务瘫痪(即没有不论什么一台计算机在执行这项服务). 分析: 题目说白了.就

CodeForces 540D Bad Luck Island 概率dp

CodeForces 540D 应该是简单概率dp,由于写得少显得十分蠢萌 求期望逆推,求概率正推,大概是这么个意思,贴一发留恋 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define db double const int maxn=108; db dp[maxn][maxn][maxn]; int main() { int i,j,n,m,k,p; whi

codeforces 148E Aragorn&#39;s Story 背包DP

Aragorn's Story Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/problem/148/E Description Our protagonist is the handsome human prince Aragorn comes from The Lord of the Rings. One day Aragorn finds a lot of enemies who

codeforces 508 E. Arthur and Brackets

题目链接: http://codeforces.ru/problemset/problem/508/E 题意: 有n对括号,按顺序,给出每对括号长度的范围,输出一种情况. 限制: 1 <= n <= 600 思路: 贪心:能匹配的先匹配. 括号匹配问题,果断先思考用栈能不能做. C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3

Codeforces 67C Sequence of Balls 编辑距离 dp

题目链接:点击打开链接 有一个交换操作比较特殊,所以记录每个点距离自己最近的那个字符的位置 然后交换就相当于把第一行要交换的2个字符 之间的字符都删掉 把第二行要交换的2个字符 之间的字符都插入第一行的2个字符之间 然后再进行交换. #include <cstdio> #include <cstring> #include<iostream> using namespace std; #define inf 10000000 #define N 4005 #define