这个问题的实例输出我是真的没搞懂,数学公式推导我都写不出来,真心不会
2条回答 默认 最新
- 谷雨553 2023-04-29 14:35关注
用动态规划来解决。可以用dp[i][j]表示区间[i,j]内括号上色的方案数。我们将左括号用数字1表示,右括号用数字2表示。那么有三种上色方案: 1.什么都不涂,表示为0 2.涂成1,表示为1 3.涂成2,表示为2 对于一个区间[i,j],我们可以枚举该区间内第一对括号的位置k,那么有两种情况: 1.第k个位置上的左括号和区间[j]上的右括号匹配,即s[k]为1,s[j]为2。那么区间[i,j]的颜色只有两种情况,一种是将s[k]和s[j]都涂成1,另一种是将它们都涂成2。因 此,我们可以得到以下递推式: dp[i][j] = (dp[i][k-1]*dp[k+1][j-1]*2) % mod 2区间[i,j]内没有可以匹配的括号对。那么我们可以将区间分成两个子区间,分别求出它们上色的方案数,然后将它们相乘。因此,我们可以得到以下递推式: dp[i][j] = (dp[i][k-1]*dp[k][j]+dp[i][k]*dp[k+1][j]) % mod
其中,k为区间[i,j]内第一对括号的位置。具体实现时,我们可以用一个栈来找到区间内第一对括号的位置。
最终答案为dp[1][n],其中n为字符串s的长度。
下面是程序,可以参考#include <iostream> #include <cstring> #include <stack> using namespace std; const int mod = 100000007; const int MAXN = 705; int dp[MAXN][MAXN]; // dp数组,表示区间[i,j]内括号上色的方案数 char s[MAXN]; // 输入的括号序列 int main() { cin >> s + 1; // 为了方便,从s[1]开始读入括号序列 int n = strlen(s + 1); stack<int> st; // 找到每一对括号的位置 for (int i = 1; i <= n; i++) { if (s[i] == '(') { st.push(i); } else { int j = st.top(); st.pop(); dp[j][i] = 1; } } // 动态规划 for (int len = 2; len <= n; len++) { for (int i = 1; i + len - 1 <= n; i++) { int j = i + len - 1; if (dp[i][j] != 0) { // 如果区间[i,j]已经匹配 for (int k = i; k < j; k++) { if (dp[i][k] != 0 && dp[k+1][j-1] != 0) { // 如果区间[i,k]和区间[k+1,j-1]都已经匹配 dp[i][j] = (dp[i][j] + dp[i][k]*dp[k+1][j-1]*2) % mod; } } } else { for (int k = i; k < j; k++) { if (dp[i][k] != 0) { dp[i][j] = (dp[i][j] + dp[i][k]*dp[k+1][j]) % mod; } if (dp[k+1][j] != 0) { dp[i][j] = (dp[i][j] + dp[i][k+1]*dp[k+2][j]) % mod; } } } } } cout << dp[1][n] << endl; return 0; }
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报 编辑记录
悬赏问题
- ¥15 phython如何实现以下功能?查找同一用户名的消费金额合并—
- ¥15 孟德尔随机化怎样画共定位分析图
- ¥18 模拟电路问题解答有偿速度
- ¥15 CST仿真别人的模型结果仿真结果S参数完全不对
- ¥15 误删注册表文件致win10无法开启
- ¥15 请问在阿里云服务器中怎么利用数据库制作网站
- ¥60 ESP32怎么烧录自启动程序
- ¥50 html2canvas超出滚动条不显示
- ¥15 java业务性能问题求解(sql,业务设计相关)
- ¥15 52810 尾椎c三个a 写蓝牙地址