HDU 5863 cjj's string game ( 16年多校10 G 题、矩阵快速幂优化线性递推DP )
题目链接
题意 : 有种不同的字符,每种字符有无限个,要求用这k种字符构造两个长度为n的字符串a和b,使得a串和b串的最长公共部分长度恰为m,问方案数
分析 :
直觉是DP
不过当时看到 n 很大、但是 m 很小的时候
发现此题DP并不合适、于是想可能是某种组合数学的问题可以直接公式算
看到题解的我、恍然大悟、对于这种数据、可以考虑一下矩阵快速幂优化的DP
首先要想到线性递推的 DP 式子
最直观的想法就是 dp[i][j] = 到第 i 个位置为止、前面最长匹配长度为 j 的方案数
但是如果仔细想想、这样子的定义状态并不好转移、遂换一种思路
定义 dp[i][j] = 到第 i 个位置为止、以第 i 个字符为结尾的匹配串的长度为 j 的方案数
有转移
dp[i][0] = (dp[i-1][0] + dp[i-1][1] + .... + dp[i-1][m] ) * k * (k-1) (k * (k-1) 的意义是a、b串第 i 个字符不一样的方案数)
dp[i][j] = dp[i-1][j-1] * k ( j ≤ i )
然后尝试去构造矩阵、此处引用 链接
但是注意一下这里的 DP 意义、答案最后并不是 dp[n][m]
dp[n][0] + dp[n][1] + ... + dp[n][m] 可以看成到第 n 个位置为止匹配长度 ≤ m 的方案数
那么如果可以得到匹配长度 ≤ m-1 的方案数两者相减就可以得到匹配长度恰为 m 的方案数了
所以做两次矩阵快速幂即可
![](/assets/blank.gif)
![](/assets/blank.gif)
#include<bits/stdc++.h> #define LL long long #define ULL unsigned long long#define scl(i) scanf("%lld", &i) #define scll(i, j) scanf("%lld %lld", &i, &j) #define sclll(i, j, k) scanf("%lld %lld %lld", &i, &j, &k) #define scllll(i, j, k, l) scanf("%lld %lld %lld %lld", &i, &j, &k, &l)#define scs(i) scanf("%s", i) #define sci(i) scanf("%d", &i) #define scd(i) scanf("%lf", &i) #define scIl(i) scanf("%I64d", &i) #define scii(i, j) scanf("%d %d", &i, &j) #define scdd(i, j) scanf("%lf %lf", &i, &j) #define scIll(i, j) scanf("%I64d %I64d", &i, &j) #define sciii(i, j, k) scanf("%d %d %d", &i, &j, &k) #define scddd(i, j, k) scanf("%lf %lf %lf", &i, &j, &k) #define scIlll(i, j, k) scanf("%I64d %I64d %I64d", &i, &j, &k) #define sciiii(i, j, k, l) scanf("%d %d %d %d", &i, &j, &k, &l) #define scdddd(i, j, k, l) scanf("%lf %lf %lf %lf", &i, &j, &k, &l) #define scIllll(i, j, k, l) scanf("%I64d %I64d %I64d %I64d", &i, &j, &k, &l)#define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 #define lowbit(i) (i & (-i)) #define mem(i, j) memset(i, j, sizeof(i))#define fir first #define sec second #define VI vector<int> #define ins(i) insert(i) #define pb(i) push_back(i) #define pii pair<int, int> #define VL vector<long long> #define mk(i, j) make_pair(i, j) #define all(i) i.begin(), i.end() #define pll pair<long long, long long>#define _TIME 0 #define _INPUT 0 #define _OUTPUT 0 clock_t START, END; void __stTIME(); void __enTIME(); void __IOPUT(); using namespace std;const int maxn = 1e5 + 10; const LL mod = 1e9 + 7;struct MAT{LL val[12][12];int sz;MAT(){};MAT(int _sz){ sz = _sz; memset(val, 0, sizeof(val)); }friend MAT operator * (const MAT & A, const MAT & B){MAT C(A.sz);for(int k = 1; k <= C.sz; k++)for(int i = 1; i <= C.sz; i++){if(A.val[i][k] == 0) continue;for(int j = 1; j <= C.sz; j++){C.val[i][j] = C.val[i][j] + A.val[i][k] * B.val[k][j] % mod;if(C.val[i][j] >= mod) C.val[i][j] -= mod;}}return C;} };MAT pow_mod(MAT a, LL b) {MAT ret(a.sz);for(int i=1; i<=ret.sz; i++) ret.val[i][i] = 1;while(b){if(b & 1) ret = ret * a;a = a * a;b >>= 1;}return ret; }LL Cal(int n, int m, int k) {MAT A(m+1);for(int i=1; i<=A.sz; i++) A.val[1][i] = 1LL * k * (k - 1);for(int i=2; i<=A.sz; i++) A.val[i][i-1] = k * 1LL;A = pow_mod(A, n);LL ret = 0;for(int i=1; i<=A.sz; i++)ret = (ret + A.val[i][1]) % mod;return ret; }int main(void){__stTIME();__IOPUT();int nCase;sci(nCase);while(nCase--){int n, m, k;sciii(n, m, k);printf("%lld\n", (Cal(n, m, k) - Cal(n, m-1, k) + mod) % mod);}__enTIME();return 0;}void __stTIME() {#if _TIMESTART = clock();#endif }void __enTIME() {#if _TIMEEND = clock();cerr<<"execute time = "<<(double)(END-START)/CLOCKS_PER_SEC<<endl;#endif }void __IOPUT() {#if _INPUTfreopen("in.txt", "r", stdin);#endif#if _OUTPUTfreopen("out.txt", "w", stdout);#endif }
View Code
转载于:https://www.cnblogs.com/LiHior/p/9797051.html
HDU 5863 cjj's string game ( 16年多校10 G 题、矩阵快速幂优化线性递推DP )相关推荐
- Recursive sequence HDU - 5950 (递推 矩阵快速幂优化)
题目链接 F[1] = a, F[2] = b, F[i] = 2 * F[i-2] + F[i-1] + i ^ 4, (i >= 3) 现在要求F[N] 类似于斐波那契数列的递推式子吧, 但 ...
- HDU 6185 Covering 矩阵快速幂 递推
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6185 题目描述: 一个4*n的矩形, 你用1*2的矩形覆盖有多少种方案, n <= 1e18 ...
- hdu 6395Sequence【矩阵快速幂】【分块】
Sequence Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Total ...
- HDU5863 cjj's string game(DP + 矩阵快速幂)
题目 Source http://acm.split.hdu.edu.cn/showproblem.php?pid=5863 Description cjj has k kinds of charac ...
- HDU 1757 A Simple Math Problem(矩阵快速幂)
题目链接 题意 :给你m和k, 让你求f(k)%m.如果k<10,f(k) = k,否则 f(k) = a0 * f(k-1) + a1 * f(k-2) + a2 * f(k-3) + -- ...
- HDU 2276 Kiki Little Kiki 2 (位运算+矩阵快速幂)
HDU 2276 Kiki & Little Kiki 2 (位运算+矩阵快速幂) ACM 题目地址:HDU 2276 Kiki & Little Kiki 2 题意: 一排灯,开关 ...
- HDU 2243考研路茫茫——单词情结 (AC自动机+矩阵快速幂)
背单词,始终是复习英语的重要环节.在荒废了3年大学生涯后,Lele也终于要开始背单词了. 一天,Lele在某本单词书上看到了一个根据词根来背单词的方法.比如"ab",放在单词前一般 ...
- hdu 5451 Best Solver 矩阵循环群+矩阵快速幂
http://acm.hdu.edu.cn/showproblem.php?pid=5451 题意:给定x 求解 思路: 由斐波那契数列的两种表示方法, 之后可以转化为 线性表示 F[n] = ...
- 湖南大学第十四届ACM程序设计新生杯(重现赛)L-The Digits String (矩阵快速幂)
题目链接 题目描述 Consider digits strings with length n, how many different strings have the sum of digits a ...
最新文章
- 华表 单元格公式设定与计算
- 作业09-集合与泛型
- Caffe中merge卷积和bn层的原理
- adb连接MuMu、逍遥、夜神、雷电模拟器以及腾讯手游助手以及断开连接
- 畅捷通(chanjet)T1各版本
- Textbox的用法
- JavaScript判断数组是否包含某元素
- WinForm中用C#实现左侧导航菜单(1)——概览
- [网络安全提高篇] 一一六.恶意代码同源分析及BinDiff软件基础用法
- ppspp android编译,PPSSPP模拟器通用设置,伪福利
- 笔记本电脑设置自动关机以及取消自动关机
- 第七届ArcGIS暨ERDAS用户大会
- java时间差的百分之二十,java计算时间差及某个时间段数据
- 顶级科学家是哲学家,顶级investor是哲学家
- transporter上传卡正在交付_Xcode11或Transporter上传app store 一直卡在Authenticating with the App Store 的解决...
- mysql错误码为1045_mysql错误代码1045的原因及解决方案
- 朗读评价语言集锦_朗读点评评语
- 基于C#面向对象的特性搭建游戏框架
- 联合CSDN官方建设新社区,奖励多多,任务简单
- 【渝粤教育】电大中专药理学基础_1作业 题库
热门文章
- Maven Oracle JDBC
- putty远程登录linux无ssh,收集的linux远程ssh连接putty失败解决办法!
- Ubuntu系统(四)-修改主机名和配置DNS上网
- java 下一代_Java 下一代: 混入和特征
- WorkFlow入门Step.3—Adding Procedural Elements-For...
- “小程序”的最佳入口位置--关于微信小程序的思考笔记
- 计算机组组内培训记录,计算机教研组活动记录
- android的命令行使用,Android命令行启动程序正确使用技巧解析
- AIR:使用 HTML + Javascript 开发桌面应用
- Xamarin For Android 打包编译APK文件详细图文教程