• CodeForces 176B Word Cut (计数DP)


    Word Cut
    Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u

    Description

    Let's consider one interesting word game. In this game you should transform one word into another through special operations.

    Let's say we have word w, let's split this word into two non-empty parts x and y so, that w = xy. A split operation is transforming wordw = xy into word u = yx. For example, a split operation can transform word "wordcut" into word "cutword".

    You are given two words start and end. Count in how many ways we can transform word start into word end, if we apply exactlyksplit operations consecutively to word start.

    Two ways are considered different if the sequences of applied operations differ. Two operation sequences are different if exists such number i (1 ≤ i ≤ k), that in the i-th operation of the first sequence the word splits into parts x and y, in the i-th operation of the second sequence the word splits into parts a and b, and additionally x ≠ a holds.

    Input

    The first line contains a non-empty word start, the second line contains a non-empty word end. The words consist of lowercase Latin letters. The number of letters in word start equals the number of letters in word end and is at least 2 and doesn't exceed 1000 letters.

    The third line contains integer k (0 ≤ k ≤ 105) — the required number of operations.

    Output

    Print a single number — the answer to the problem. As this number can be rather large, print it modulo 1000000007(109 + 7).

    Sample Input

    Input
    ab
    ab
    2
    Output
    1
    Input
    ababab
    ababab
    1
    Output
    2
    Input
    ab
    ba
    2
    Output
    0

    Hint

    The sought way in the first sample is:

    ab → a|b → ba → b|a → ab

    In the second sample the two sought ways are:

    • ababab → abab|ab → ababab
    • ababab → ab|abab → ababab

    【题意】:

    划分一个串:w = xy into u = yx(整体顺序改变,内容不变)

    问有多少种方式,使得正好经过K次划分,从原串变成目的串。

    【解题思路】:

    比较典型的计数DP。

    观察到划分只是改变相对顺序,如果把串看成首尾相接的环,则划分只是改变起始点。

    转移过程:(经过i次划分,有多少种方式到这个串)

    起始:原串方式数=1;其他串方式数=0

    第一次:原串=0(因为不能变成自己);其他=1(从起始的原串而来)

    第二次:原串=n-1(所有其它串都可以变回来);其他=n-2(除去本身的其他+原串)

    ……

    DP状态应该是划分的次数k和起始点i

    但是用滚动数组可以消去划分次数这个维度;所以实现起来就是两个数(分别代表原串和其他)在不停迭代。

    最后比较哪些起点对应目标串,做一个累加即可。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<algorithm>
     6 #include<vector>
     7 #define LL long long
     8 #define maxn 10010
     9 #define inf 0x3f3f3f3f
    10 #define mod 1000000007
    11 #define IN freopen("in.txt","r",stdin);
    12 using namespace std;
    13 
    14 
    15 int main(int argc, char const *argv[])
    16 {
    17     //IN;
    18 
    19     string a,b;
    20     cin >> a >> b;
    21     int s = a.size();
    22     int n;
    23     cin >> n;
    24 
    25     LL ans1 = 1;
    26     LL ans2 = 0;
    27     LL tmp = 0;
    28     for(int i=1; i<=n; i++){
    29         tmp = ans1;
    30         ans1 = (ans2 * (s-1))%mod;
    31         ans2 = (tmp + (ans2*(s-2))%mod)%mod;
    32     }
    33 
    34     LL ans = 0;
    35     for(int i=0; i<s; i++){
    36         int j;
    37         for(j=i; j<i+s; j++){
    38             if(b[j-i] != a[j%s]) break;
    39         }
    40         if(j == i+s){
    41             if(!i) ans = (ans+ans1)%mod;
    42             else ans = (ans+ans2)%mod;
    43         }
    44     }
    45 
    46     printf("%I64d
    ", ans);
    47 
    48     return 0;
    49 }
  • 相关阅读:
    KMP算法与字符串匹配问题
    贪婪算法(贪心算法)
    普里姆算法(Prim)与最小生成树问题
    克鲁斯卡尔算法(Kruskal算法)与最小生成树问题
    Dijkstra算法与最短路径问题
    SpringCloud(十一)使用actuator和dashborad、turbine对微服务进行监控
    博客美化——页面白天黑夜切换
    Spring5学习笔记——day01
    Mybatis学习笔记——day06
    Mybatis学习笔记——day05
  • 原文地址:https://www.cnblogs.com/Sunshine-tcf/p/5327463.html
Copyright © 2020-2023  润新知