zoukankan      html  css  js  c++  java
  • [CF1499E] Chaotic Merge

    [CF1499E] Chaotic Merge - dp

    Description

    给定两个仅由小写字母组成的字符串 (x)(y)。如果一个序列仅包含 (|x|)(0)(|y|)(1),则称这个序列为合并序列。若一个字符串任意两个相邻位置上的字符都不同,则我们称该字符串是混乱的。定义 (f(l_1,r_1,l_2,r_2)) 表示能从 (x) 的子串 (x[l_1,r_1])(y) 的子串 (y[l_2,r_2]) 生成混乱的字符串的不同的合并序列的数量,要求子串非空。求 (sum limits_{1 le l_1 le r_1 le |x| , 1 le l_2 le r_2 le |y|} f(l_1, r_1, l_2, r_2))

    Solution

    先不考虑选子串,先考虑整个串,设 (f[i][j][0/1]) 表示取了 (x[1..i], y[1..j]) 进行合并,最后一个字符是 (x[i]) 还是 (y[j]),此时的方案数是多少

    现在把子串的问题带进来,右端点实际上已经包含在我们的状态中了,所以我们实际需要考虑的是左端点

    考虑在先前的版本上做点修改,状态设计不变,对每个状态,额外引入一个从这里开始一个新的串(即一边长度为 (1))的方案数

    细节需要调教一下

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    const int N = 1005;
    const int mod = 998244353;
    
    int f[N][N][2], fx[N], fy[N], n, m;
    
    string x, y;
    
    signed main()
    {
        ios::sync_with_stdio(false);
        cin >> x >> y;
        x = " " + x;
        y = " " + y;
        string &a = x;
        string &b = y;
    
        n = x.length() - 1;
        m = y.length() - 1;
    
        int ans = 0;
    
        for (int i = 1; i <= n; i++)
        {
            if (a[i] != a[i - 1])
                f[i][0][0] = f[i - 1][0][0] + 1;
            else
                f[i][0][0] = 1;
        }
    
        for (int j = 1; j <= m; j++)
        {
            if (b[j] != b[j - 1])
                f[0][j][1] = f[0][j - 1][1] + 1;
            else
                f[0][j][1] = 1;
        }
    
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= m; j++)
            {
                if (i > 1 && a[i] != a[i - 1])
                    f[i][j][0] += f[i - 1][j][0];
                if (i > 1 && a[i] != b[j])
                    f[i][j][0] += f[i - 1][j][1];
                if (j > 1 && a[i] != b[j])
                    f[i][j][1] += f[i][j - 1][0];
                if (j > 1 && b[j] != b[j - 1])
                    f[i][j][1] += f[i][j - 1][1];
                if (a[i] != b[j])
                {
                    f[i][j][0] += f[0][j][1];
                    f[i][j][1] += f[i][0][0];
                }
                f[i][j][0] %= mod;
                f[i][j][1] %= mod;
                ans += f[i][j][0];
                ans += f[i][j][1];
                ans %= mod;
            }
        }
        cout << ans << endl;
    }
    
  • 相关阅读:
    移动端div移动
    js获取网页高度
    css cursor 的可选值(鼠标的各种样式)
    HTML5 拖动
    函数式编程中的常用技巧
    CoolShell Puzzle攻略[更新隐藏剧情]
    Web性能测试-词汇
    STM32库函数 断言机制 宏定义assert_param(expr)和assert_failed的使用方法
    arm汇编:伪指令ldr分析
    Altium designer 16 Mechanical1层之PCB 打样说明
  • 原文地址:https://www.cnblogs.com/mollnn/p/14603853.html
Copyright © 2011-2022 走看看