codeforces 176 B. Word Cut(DP)

本文介绍了一种通过数学推导和特定处理方式解决字符串转换问题的方法。对于给定的两个字符串a和b,以及操作步数k,文章详细阐述了如何计算能够通过不同操作将a转换为b的次数。

对于一个字符串,我们可以对它作这样一种操作

把前面一部分整体移至字符串结尾

给定字符串a,b和操作步数k

问你能通过多少次不同操作使a变为b

这个题看起来很复杂,但其实是道数学推导题+一些处理

先不考虑a自身是重复的,则我们通过列举abc这个字符串的情况可以发现一些规律


按深度发现ABC出现次数的规律以及其他字符串出现的规律

对于自身含有重复部分的,我们要加上它重复的次数×对应结果

代码如下:

#include <bits/stdc++.h>
#define LL long long
#define MOD 1000000007
using namespace std;

string st1, st2;
int dp[3][3];

int main(void) {

    int k, pos, len;
    cin >> st1 >> st2;
    scanf("%d", &k);
    len = st1.size();

    //dp[i][j] = sum[i-1]-dp[i-1][j];

    memset(dp, 0, sizeof(dp));

    dp[0][1] = 1;

    LL tmp = 1;
    for(int i=1; i<=k; ++i) {
        for(int j=1; j<=2; ++j) {
            dp[i&1][j] = (tmp+MOD-dp[1-(i&1)][j])%MOD;
        }
        //printf("%lld\n", tmp);
        tmp = (tmp*(len-1))%MOD;
        //printf("dp -- %d\t%d\n", dp[i&1][1], dp[i&1][2]);
    }

    int i, j, L;
    LL ans = 0;
    for(i=0; i<len; ++i) {
        L = i;
        for(j=0; j<len; ++j) {
            if(st1[L] != st2[j])
                break;
            L = (L+1)%len;
        }
        if(j >= len)
            ans = i ? (ans+dp[k&1][2])%MOD : (ans+dp[k&1][1])%MOD;
    }

    cout << ans << endl;
    
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值