• 组合数+dp


    • 给出一个小写字母字符串 T,长度为 nnn。
    • 求有多少长度为 m(m≤105)m (m\leq10^5)m(m≤105) 的小写字母字符串 S,满足 T 是 S 的一个子序列。
    • 我们从合法的新串下手,考虑制定出一种方法来从中找出原串。

    • 对这种方法的要求是:按照这种方法 找出的新串 的下标 必须唯一。

    • 一种合理的匹配方式是:

      • 假如原串是:abcabcabc
      • 假如新串是:aaabbbcccaaabbbccaaccaaabbbcccaaabbbccaaccaaabbbcccaaabbbccaacc
      • 匹配应该是:aaabbbcccaa[a]bb[b]ccaac[c]aaabbbcccaa[a]bb[b]ccaac[c]aaabbbcccaa[a]bb[b]ccaac[c]
      • 匹配规则是:对于某个被匹配到的字符 chchch 开始,从它右边第一个开始,到它右边下一个被匹配的字符左边第一个为止,不得出现跟 chchch 相同的字符。
      • 能发现,按照这种方法 找出的新串 的下标是唯一的。
      • 总结一下这种匹配方式:
        • 我们知道,由子序列 SSS 构造原序列 TTT,问方案数这类问题,就是要保证,
        • 如果你在 TTT 确定 TTT 的第 iii 个字符 tit_iti​,匹配的是 SSS 中的第 ppp 个字符 sps_psp​,
        • 并且你在 TTT 确定 TTT 的第 jjj 个字符 tjt_jtj​,匹配的是 SSS 中的第 p+1p+1p+1 个字符 sp+1s_{p+1}sp+1​,
        • 除了 ti=spt_i=s_pti​=sp​,tj=sp+1t_j=s_{p+1}tj​=sp+1​ 以外,还要保证,ti+1...tj−1t_{i+1}...t_{j-1}ti+1​...tj−1​ 的所有字符,都不包含 tit_iti​。
    • 现在考虑按照这种匹配思路,从原串开始,构造新串。

      1. void Sol()
      2. {
      3. dp[0][0] = 1;
      4. for (int i=1; i<=m; i++) //从你决定开始匹配原串第一个字符之前,放什么都行,每一个位置有26种放法。
      5. {
      6. dp[i][0] = dp[i-1][0] * 26 % MOD;
      7. }
      8. for (int i=1; i<=m; i++)//枚举新串
      9. {
      10. for (int j=1; j<=min(i, n); j++)//枚举原串
      11. {
      12. //对于新串的第 i 个字符,有两种情况:
      13. //一种是第i个字符匹配上原串的第j个字符
      14. //一种是第i个字符在前i-1个已经匹配上原串的第j个字符的情况下,有25种放法。
      15. dp[i][j] += (j-1<0?0:dp[i-1][j-1]) + dp[i-1][j] * 25 % MOD, dp[i][j] %= MOD;
      16. }
      17. }
      18. printf("%lld\n",dp[m][n]);

      链接:登录—专业IT笔试面试备考平台_牛客网
      来源:牛客网

      Link doesn't remember bbb, so he wonders the number of possible sequences bbb.
       

      A bracket sequence is valid if it satisfies any of the following conditions:

    • Its length is 000.
    • It can be represented as (A)(A)(A), where AAA is a valid bracket sequences.
    • It can be represented as ABABAB, where AAA and BBB are both valid bracket sequence.

    • A sequence aaa is a subsequence of a sequence bbb if aaa can be obtained from bbb by deletion of several (possibly, zero or all) elements.

      1. #include
      2. #include
      3. #include
      4. #include
      5. using namespace std;
      6. typedef long long ll;
      7. const int N=205,mod=1e9+7;
      8. ll dp[N][N][N];
      9. void solve()
      10. {
      11. int n,m;cin>>n>>m;
      12. string s;
      13. cin>>s;
      14. for(int i=0;i<=n;i++)
      15. {
      16. for(int j=0;j<=m;j++)
      17. {
      18. for(int k=0;k<=m;k++) dp[i][j][k]=0;
      19. }
      20. }
      21. dp[0][0][0]=1;
      22. for(int i=1;i<=m;i++)
      23. {
      24. for(int j=0;j<=i;j++)
      25. {
      26. dp[0][i][j]+=(j-1<0?0:dp[0][i-1][j-1])+dp[0][i-1][j+1];
      27. dp[0][i][j]%=mod;
      28. }
      29. }
      30. for(int i=1;i<=m;i++)
      31. {
      32. for(int j=1;j<=min(i,n);j++)
      33. {
      34. for(int k=0;k<=i;k++)
      35. {
      36. int d=-1+2*(s[j-1]=='(');
      37. if(k-d>=0&&k-d<=m) dp[j][i][k]+=dp[j-1][i-1][k-d];
      38. if(k+d<=m&&k+d>=0) dp[j][i][k]+=dp[j][i-1][k+d];
      39. dp[j][i][k]%=mod;
      40. }
      41. }
      42. }
      43. cout<0]<
      44. }
      45. int main()
      46. {
      47. int t;cin>>t;
      48. while(t--)
      49. {
      50. solve();
      51. }
      52. }

  • 相关阅读:
    【爬虫】Python使用动态IP,多线程,爬取uncomtrade的数据
    【C语言】调试
    Cobalt Strike(三)DNS bacon 的使用与原理
    单例模式的安全写法
    地质学中 P-A 图(PA图)讲解并使用python实现 || plt绘图实现,一个坐标图共享两个左右y轴
    【PyG】文档总结以及项目经验(持续更新
    基于web在线餐饮网站的设计与实现——蛋糕甜品店铺(HTML+CSS+JavaScript)
    SQL 递归思想
    引擎之旅 Chapter.2 线程库
    【手把手带你学JavaSE】第五篇:Java中的数组
  • 原文地址:https://blog.csdn.net/qq_52004482/article/details/126724554