Codeforces 176B Word Cut
2018-02-22 14:49
246 查看
Description
题面题目大意:给定两个串A,B,每一次可以翻转A串的两个部分,如A=XY->YX,问恰好经过K次操作变成B串的方案数
Solution
需要注意到一个问题:本质不同的串最多只有 \(n-1\) 个可以把A看成一个环,每一次翻转相当于改变一个起点
于是我们可以归类为两种串:1.原串 2.非原串
原串可以产生\(n-1\)个非原串,非原串可以产生 \(n-2\) 个非原串和 \(1\) 个原串
注意到:变成所有的非原串的方案数都是一样的
因为非原串中并不一定所有的都等于B,所以还需要枚举B等于哪几个非原串,判定加上几个非原串的贡献
设 \(f[i][0/1]\) 表示产生原串的方案数和产生非原串的方案数
\(f[i][0]=f[i-1][1]*(n-1)\)
\(f[i][1]=f[i-1][0]+(n-2)*f[i-1][1]\)
#include<bits/stdc++.h> using namespace std; const int N=1e5+10,mod=1e9+7; int ans=0,f [2],K,n;char a ,b ; inline bool check(int x){ for(int i=1;i<=n;i++){ if(a[x]!=b[i])return false; x++;if(x==n+1)x=1; } return true; } int main(){ scanf("%s%s%d",a+1,b+1,&K); n=strlen(a+1); f[0][0]=1; for(int i=1;i<=K;i++){ f[i][0]=1ll*f[i-1][1]*(n-1)%mod; f[i][1]=(f[i-1][0]+1ll*f[i-1][1]*(n-2))%mod; } for(int i=1;i<=n;i++){ if(check(i)){ if(i==1)ans=(ans+f[K][0])%mod; else ans=(ans+f[K][1])%mod; } } cout<<ans<<endl; return 0; }
相关文章推荐
- Codeforces189 A. Cut Ribbon(DP)
- CF 176B Word Cut
- Codeforces-----614A---Link/Cut Tree---数学水题
- 【CodeForces 614A】Link/Cut Tree
- codeforces189 A. Cut Ribbon【完全背包】
- Codeforces-189A-Cut Ribbon
- CodeForces 题目191C. Fools and Roads(Link Cut Tree,边权加求边权值)
- codeforces——189A——Cut Ribbon
- BZOJ-4424 &&CodeForces-19E Fairy DP+dfs (Link-Cut-Tree可A)
- codeforces 176B - Word Cut DP
- CodeForces 614 A. Link/Cut Tree(水~)
- BZOJ-4424 &&CodeForces-19E Fairy DP+dfs (Link-Cut-Tree可A)
- Codeforces Round #339 (Div. 2) A. Link/Cut Tree - Codeforces(思维)
- [BZOJ4424]CodeForces 19# E Fairy(树形dp / Link-Cut-tree)
- codeforces 614 A. Link/Cut Tree
- [Codeforces 176B] Word Cut (脑洞+KMP+dp)
- Codeforces--614A--Link/Cut Tree(数学)(暴力求解)
- 【CodeForces】[614A]Link/Cut Tree
- 【Codeforces 176B】 Word Cut
- codeforces 727F Polycarp's problems