题目大意:给你两个长度都为n,字符集为{a,b,c}的字符串S和T。

对于字符串S的任意一个字符,我们可以用cost[0]的代价,把字符a变成字符b。用cost[1]的代价,把字符b变成c,用cost[2]的代价,把字符c变成a。

问你在总代价不超过MaxCost的情况下,有多少种方法,使得字符串S与字符串T相同。

两种方法被认为是不同的,当且仅当操作序列的长度是不同的,或者某一步操作的字符不同。

数据范围:$n≤11$,$1≤cost≤10^9$,$0≤MaxCost≤10^9$。

我们先用最少的代价使得$S=T$。不妨设该过程耗费的代价为$MinCost$,操作步数为$MinK$。

我们不难发现,接下来如果某个位置的字符需要发生变化,则该字符必须变化一整圈(变化3次),花费为$cost[0]+cost[1]+cost[2]$。

那么,变化的圈数显然不会超过$(MaxCost-MinCost)/(cost[0]+cost[1]+cost[2])$,我们令该值为$K$。

令$f[X][i][j][k]$表示第$X$次操作时,串$S$满足有$i$个位置与串$T$相同,有$j$个位置需要转$1$次才能与$T$相同,有$k$个位置需转$2$次才能与$T$相同。

显然,我们可以用$f[X][i][j][k]$,去更新:$f[X+1][i-1][j+1][k],f[X+1][i][j-1][k+1],f[i+1][j][k-1]$

不难发现我们可以用矩阵快速幂来加速转移。

考虑到$f[X][i][j][k]$需满足$i+j+k=0$。不难发现矩阵大小上限是$n^2\times n^2$的。

然后就做完了

时间复杂度:$O(n^6\log\ \frac{MaxCost}{Cost})$

 #include<bits/stdc++.h>
#define N 11
#define M 82
#define L long long
#define MOD 1000000007
#define A 'a'
#define B 'b'
#define C 'c'
using namespace std; struct mat{
L a[M][M]; int n,m;
mat(){memset(a,,sizeof(a)); n=m=;}
mat(int _n,int _m){n=_n; m=_m; memset(a,,sizeof(a));}
void dw(){
memset(a,,sizeof(a));
for(int i=;i<=n;i++) a[i][i]=;
}
friend mat operator *(mat a,mat b){
mat c=mat(a.n,b.m);
for(int i=;i<=a.n;i++)
for(int j=;j<=a.m;j++)
for(int k=;k<=b.n;k++){
if(a.a[i][k]*b.a[k][j]){
int yxq;
yxq=;
}
c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%MOD;
}
return c;
}
friend mat operator ^(mat a,int b){
mat ans=mat(a.n,a.n); ans.dw();
while(b){
if(b&) ans=ans*a;
a=a*a; b>>=;
}
return ans;
}
};
mat S,sta; int c[][]={},h[][]={}; int n,times=,lim,k=; char s[]={},t[]={};
int Init(){
scanf("%s%s",s,t); n=strlen(s);
scanf("%d%d%d",&c[A][B],&c[B][C],&c[C][A]);
c[A][C]=c[A][B]+c[B][C];
c[B][A]=c[B][C]+c[C][A];
c[C][B]=c[C][A]+c[A][B];
h[A][B]=h[B][C]=h[C][A]=;
h[B][A]=h[C][B]=h[A][C]=;
scanf("%d",&lim);
int dn=;
for(int i=;i<n;i++){
k+=h[s[i]][t[i]];
dn+=c[s[i]][t[i]];
}
k+=(lim-dn)/(c[A][B]+c[B][C]+c[C][A])*;
} int id[N][N][N]={},cnt=;
void BuildMatrix(){
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
for(int k=;k<=n;k++)
if(i+j+k==n){
id[i][j][k]=++cnt;
}
S=mat(cnt+,cnt+); sta=mat(,cnt+);
int p[]={};
for(int i=;i<n;i++) p[h[t[i]][s[i]]]++;
sta.a[][id[p[]][p[]][p[]]]=; for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
for(int k=;k<=n;k++)
if(i+j+k==n){
int ID=id[i][j][k],P=; if(i->=) P=id[i-][j+][k]; else P=;
if(P) S.a[ID][P]=i; if(j->=) P=id[i][j-][k+]; else P=;
if(P) S.a[ID][P]=j; if(k->=) P=id[i+][j][k-]; else P=;
if(P) S.a[ID][P]=k;
}
S.a[cnt+][cnt+]=S.a[id[n][][]][cnt+]=;
} int main(){
Init();
BuildMatrix();
S=S^k;
sta=sta*S;
cout<<(sta.a[][cnt+]+sta.a[][id[n][][]])%MOD<<endl;
}

【xsy1237】 字符转换 矩阵快速幂的更多相关文章

  1. hdu2604 递推转换矩阵快速幂

    刚开始还以为用位运算与或几下几个循环就搞定了,算着算着发现不行........ 还是一种固定的切题角度,我假设有长度为n,总的排列数位f(n),怎么算他呢?从后往前考虑,因为大多数情况,都是用前面的结 ...

  2. BZOJ2553 Beijing2011禁忌(AC自动机+动态规划+矩阵快速幂+概率期望)

    考虑对一个串如何分割能取得最大值.那么这是一个经典的线段覆盖问题,显然每次取右端点尽量靠前的串.于是可以把串放在AC自动机上跑,找到一个合法串后就记录并跳到根. 然后考虑dp.设f[i][j]表示前i ...

  3. UVA-11625-Nice Prefixes (DP+矩阵快速幂)

    题目(vjudge) 题面 题意: 你有K个字母,你需要用K个字母组成L长度的字符串,定义对于该字符串的任意前缀P 必须满足    ,输出方案数%1000000007的值. 思路: 首先可以想到一种简 ...

  4. hdu2604(递推,矩阵快速幂)

    题目链接:hdu2604 这题重要的递推公式,找到公式就很easy了(这道题和hdu1757(题解)类似,只是这道题需要自己推公式) 可以直接找规律,推出递推公式,也有另一种找递推公式的方法:(PS: ...

  5. [HDOJ2604]Queuing(递推,矩阵快速幂)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2604 递推式是百度的,主要是练习一下如何使用矩阵快速幂优化. 递推式:f(n)=f(n-1)+f(n- ...

  6. CCF 201312-4 有趣的数 (数位DP, 状压DP, 组合数学+暴力枚举, 推公式, 矩阵快速幂)

    问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次. 2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前. 3. 最高 ...

  7. BZOJ 1009: [HNOI2008]GT考试( dp + 矩阵快速幂 + kmp )

    写了一个早上...就因为把长度为m的也算进去了... dp(i, j)表示准考证号前i个字符匹配了不吉利数字前j个的方案数. kmp预处理, 然后对于j进行枚举, 对数字0~9也枚举算出f(i, j) ...

  8. hihocoder第42周 3*N骨牌覆盖(状态dp+矩阵快速幂)

    http://hihocoder.com/contest/hiho42/problem/1 给定一个n,问我们3*n的矩阵有多少种覆盖的方法 第41周做的骨牌覆盖是2*n的,状态转移方程是dp[i] ...

  9. poj 2778 AC自动机+矩阵快速幂

    题目链接:https://vjudge.net/problem/POJ-2778 题意:输入n和m表示n个病毒,和一个长为m的字符串,里面只可以有'A','C','G','T' 这四个字符,现在问这个 ...

随机推荐

  1. 换行符在HTML中直接替换为<br>

         #set($text=$!obj.getMeasure().replaceAll("\r\n","<br>"))     <td a ...

  2. const变量指针赋值给非const类型的指针运行结果

    在c++可以定义一个const变量,然后把变量的值赋给一个非const指针,可以通过指针来改变const变量的值吗?下面的截图给出了答案

  3. python的基础操作2

    一 字符串格式化 占位符 %s和%d %s是属于字符串的占位符,而%d是属于数字类型的占位符 #占位符 %s %d # a="我叫%s,年龄%d,就是一个%s"%("al ...

  4. 2018.09.15 hdu3018Ant Trip(欧拉路)

    传送门 显然答案等于各个连通分量的笔画数之和. 因此我们dfs每个连通分量计算对答案的贡献. 对于一个连通分量,如果本来就有欧拉回路那么只需要一笔. 否则需要寄点数/2那么多笔才能画完. 知道这个结论 ...

  5. UVa 508 Morse Mismatches (模糊暴力)

    题意:莫尔斯电码,输入若干个字母的Morse编号,一个字典和若干编码.对于每个编号,判断它可能的是哪个单词, 如果有多个单词精确匹配,输出第一个单词并加一个“!”:如果无法精确匹配,那么在编码尾部增加 ...

  6. UVa 10382 Watering Grass (区间覆盖贪心问题+数学)

    题意:有一块长为l,宽为w的草地,在其中心线有n个喷水装置,每个装置可喷出以p为中心以r为半径的圆, 选择尽量少的装置,把草地全部润湿. 析:我个去啊,做的真恶心,看起来很简单,实际上有n多个坑啊,首 ...

  7. 201709021工作日记--Volley源码解读(四)

    接着volley源码(三)继续,本来是准备写在(三)后面的,但是博客园太垃圾了,写了半天居然没保存上,要不是公司这个博客还没被限制登陆,鬼才用这个...真是垃圾 继续解读RequestQueue的源码 ...

  8. Global Mapper

    https://blog.csdn.net/mrib/article/details/75116373 http://www.bluemarblegeo.com/products/global-map ...

  9. (最小生成树) 畅通工程再续 -- HDU --1875

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=1875 http://acm.hust.edu.cn/vjudge/contest/view.action ...

  10. Spring组件扫描 <context:component-scan/>

    目录(?)[-] 总结 使用方式 扫描controller下所以类 扫描符合条件Controller的类推荐 我们在SpringMVC开发项目中,有的用注解和XML配置Bean,这两种都各有自己的优势 ...