BZOJ 4037 [HAOI2015]数字串拆分 ——动态规划
拆分的情况下,发现f数组本身并不是很好递推。
因为f(123)=f(123)/f(12+3)/f(1+2+3)。
然后考虑f可以怎么表示f(n)=a0*M^n M为转移矩阵。
然后发现 f(x+y)=a0*M(x+y), 所以只需要对M矩阵进行DP即可。
这样子每一个位置就可以表示为若干转移矩阵的和,然后就可以利用矩阵的相乘进行递推。
最后直接用原向量乘上转移矩阵即可。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; #define ll long long
#define F(i,j,k) for (ll i=j;i<=k;++i)
#define D(i,j,k) for (ll i=j;i>=k;--i)
const ll md=998244353; ll m,l;char s[505]; struct matrix{
ll x[6][6];
void init(){memset(x,0,sizeof x);}
void build1(){
init();
x[1][1]=1;
}
void build2(){
init();
F(i,1,m) x[i][1]=1;
F(i,1,m-1) x[i][i+1]=1;
}
void build3(){
init();
F(i,1,m) x[i][i]=1;
}
matrix operator * (matrix b) {
matrix ret;
ret.init();
F(i,1,m) F(j,1,m)
{
F(k,1,m)
ret.x[i][j]=ret.x[i][j]+x[i][k]*b.x[k][j];
ret.x[i][j]%=md;
}
return ret;
}
matrix operator + (matrix b) {
matrix ret;
ret.init();
F(i,1,m) F(j,1,m)
ret.x[i][j]=((ll)x[i][j]+(ll)b.x[i][j])%md;
return ret;
}
}dp[505],one,c[11][501],turn,now,ans; int main()
{
scanf("%s",s+1);l=strlen(s+1);
scanf("%lld",&m);
F(i,0,l) dp[i].init();
one.build1();
turn.build2();
c[0][0].build3();
F(i,1,10) c[i][0]=c[i-1][0]*turn;
F(i,1,l-1)
{
c[0][i]=c[0][i-1];
c[1][i]=c[10][i-1];
F(j,2,10)
{
c[j][i]=c[j-1][i]*c[10][i-1];
}
}
dp[0].build3();
F(i,1,l)
{
now.build3();
D(j,i,1)
{
now=now*c[s[j]-'0'][i-j];
dp[i]=dp[i]+dp[j-1]*now;
}
}
ans=dp[l]*one;
printf("%lld\n",ans.x[1][1]);
}
BZOJ 4037 [HAOI2015]数字串拆分 ——动态规划的更多相关文章
- bzoj 4037: [HAOI2015]数字串拆分【dp+矩阵加速】
首先f长得就很像能矩阵优化的,先构造转移矩阵(这里有一点神奇的地方,我看网上的blog和我构造的矩阵完全不一样还以为我的构造能力又丧失了,后来惊奇的发现我把那篇blog里的构造矩阵部分换成我的构造方式 ...
- BZOJ4037:[HAOI2015]数字串拆分——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4037 你有一个长度为n的数字串.定义f(S)为将S拆分成若干个1~m的数的和的方案数,比如m=2时 ...
- [HAOI2015]数字串拆分
题目描述 你有一个长度为n的数字串.定义f(S)为将S拆分成若干个1~m的数的和的方案数,比如m=2时,f(4)=5,分别为4=1+1+1+1你可以将这个数字串分割成若干个数字(允许前导0),将他们加 ...
- bzoj4037 [HAOI2015]数字串拆分
Description 你有一个长度为n的数字串.定义f(S)为将S拆分成若干个1~m的数的和的方案数,比如m=2时,f(4)=5,分别为4=1+1+1+1你可以将这个数字串分割成若干个数字(允许前导 ...
- 洛谷3176 [HAOI2015]数字串拆分 (矩阵乘法+dp)
qwq真的是一道好题qwq自己做基本是必不可能做出来的. 首先,如果这个题目只是求一个\(f\)数组的话,那就是一道裸题. 首先,根据样例 根据题目描述,我们能发现其实同样数字的不同排列,也是属于不同 ...
- loj#2128. 「HAOI2015」数字串拆分 矩阵乘法
目录 题目链接 题解 代码 题目链接 loj#2128. 「HAOI2015」数字串拆分 题解 \(f(s)\)对于\(f(i) = \sum_{j = i - m}^{i - 1}f(j)\) 这个 ...
- 【LOJ】#2128. 「HAOI2015」数字串拆分
题解 题中给的函数可以用矩阵快速幂递推 我们记一个数组dp[i](这个数组每个元素是一个矩阵)表示从1到i所有的数字经过拆分矩阵递推的加和 转移方法是 \(dp[i] = \sum_{j = 0}^{ ...
- [bzoj P4504] K个串
[bzoj P4504] K个串 [题目描述] 兔子们在玩k个串的游戏.首先,它们拿出了一个长度为n的数字序列,选出其中的一个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计一次 ...
- 解决 PHPExcel 长数字串显示为科学计数
解决 PHPExcel 长数字串显示为科学计数 在excel中如果在一个默认的格中输入或复制超长数字字符串,它会显示为科学计算法,例如身份证号码,解决方法是把表格设置文本格式或在输入前加一个单引号. ...
随机推荐
- IOS之TextView属性设置
UIFontDescriptor *bodyFontDescriptor = [UIFontDescriptor preferredFontDescriptorWithTextStyle:UIFont ...
- ycsb模板介绍
#对应的mongodb uri参数等mongodb.url=mongodb://127.0.0.1:27010/test_1 #对应的mongo数据库名称mongodb.database=test_1 ...
- JS 一个页面关闭多个页面
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head><meta ...
- win7 ghost 纯净版最新系统下载
这个系统是WIN7系统GHOST版装机旗舰版 SP1,更新了系统补丁到2016-02(可通过微软漏洞扫描和卫士漏洞扫描),升级Internet Explorer为IE9,增加数款驱动的支持,支持最新的 ...
- 数据倾斜是多么痛?spark作业调优秘籍
目录视图 摘要视图 订阅 [观点]物联网与大数据将助推工业应用的崛起,你认同么? CSDN日报20170703——<从高考到程序员——我一直在寻找答案> [直播]探究L ...
- 关于 QObject 类
1.QObject类 简述 QObject类是所有Qt对象的基类. QObject是Qt对象模型的核心. 该模型的核心特征是称为信号和槽的对象通信机制. 您可以使用connect()将信号连接到槽 ...
- CS 分解
将学习到什么 CS 分解是分划的酉矩阵在分划的酉等价之下的标准型. 它的证明涉及奇异值分解.QR 分解以及一个简单习题. 一个直观的习题 设 \(\Gamma, L \in M_p\). 假设 \ ...
- 基于Passthru的NDIS开发的个人理解
这几天对NDIS的学习,基本思路是:首先熟悉理论知识→然后下载一个例子进行研究→最后例子自己模仿扩展→最最后尝试自己写一个新的. Passthru是微软NDIS自己写的一个框架驱动,NDIS开发者可以 ...
- 通过工厂模式批量创建对象后调用其中方法 出现XXXis not a function()问题原因
//通过工厂模式批量创建 function Computer(color,weight,logo){ var obj=new Object(); obj.color=c ...
- POJ 2255 Tree Recovery——二叉树的前序遍历、后序遍历、中序遍历规则(递归)
1.前序遍历的规则:(根左右) (1)访问根节点 (2)前序遍历左子树 (3)前序遍历右子树 对于图中二叉树,前序遍历结果:ABDECF 2.中序遍历的规则:(左根右) (1)中序遍历左子树 (2)访 ...