拆分的情况下,发现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]数字串拆分 ——动态规划的更多相关文章

  1. bzoj 4037: [HAOI2015]数字串拆分【dp+矩阵加速】

    首先f长得就很像能矩阵优化的,先构造转移矩阵(这里有一点神奇的地方,我看网上的blog和我构造的矩阵完全不一样还以为我的构造能力又丧失了,后来惊奇的发现我把那篇blog里的构造矩阵部分换成我的构造方式 ...

  2. BZOJ4037:[HAOI2015]数字串拆分——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4037 你有一个长度为n的数字串.定义f(S)为将S拆分成若干个1~m的数的和的方案数,比如m=2时 ...

  3. [HAOI2015]数字串拆分

    题目描述 你有一个长度为n的数字串.定义f(S)为将S拆分成若干个1~m的数的和的方案数,比如m=2时,f(4)=5,分别为4=1+1+1+1你可以将这个数字串分割成若干个数字(允许前导0),将他们加 ...

  4. bzoj4037 [HAOI2015]数字串拆分

    Description 你有一个长度为n的数字串.定义f(S)为将S拆分成若干个1~m的数的和的方案数,比如m=2时,f(4)=5,分别为4=1+1+1+1你可以将这个数字串分割成若干个数字(允许前导 ...

  5. 洛谷3176 [HAOI2015]数字串拆分 (矩阵乘法+dp)

    qwq真的是一道好题qwq自己做基本是必不可能做出来的. 首先,如果这个题目只是求一个\(f\)数组的话,那就是一道裸题. 首先,根据样例 根据题目描述,我们能发现其实同样数字的不同排列,也是属于不同 ...

  6. loj#2128. 「HAOI2015」数字串拆分 矩阵乘法

    目录 题目链接 题解 代码 题目链接 loj#2128. 「HAOI2015」数字串拆分 题解 \(f(s)\)对于\(f(i) = \sum_{j = i - m}^{i - 1}f(j)\) 这个 ...

  7. 【LOJ】#2128. 「HAOI2015」数字串拆分

    题解 题中给的函数可以用矩阵快速幂递推 我们记一个数组dp[i](这个数组每个元素是一个矩阵)表示从1到i所有的数字经过拆分矩阵递推的加和 转移方法是 \(dp[i] = \sum_{j = 0}^{ ...

  8. [bzoj P4504] K个串

    [bzoj P4504] K个串 [题目描述] 兔子们在玩k个串的游戏.首先,它们拿出了一个长度为n的数字序列,选出其中的一个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计一次 ...

  9. 解决 PHPExcel 长数字串显示为科学计数

    解决 PHPExcel 长数字串显示为科学计数 在excel中如果在一个默认的格中输入或复制超长数字字符串,它会显示为科学计算法,例如身份证号码,解决方法是把表格设置文本格式或在输入前加一个单引号. ...

随机推荐

  1. Chisel语言

    1 What is Chisel?      Chisel(Constructing Hardware In a Scala Embedded Language)是一种嵌入在高级编程语言Scala的硬 ...

  2. smarty 运算符列表

    下面是可用的运算符列表,使用中都会放到元素的中间并且用空格分隔. 注意列表中[方括号]的是可选的,而且还会列出对应PHP的表达式. 详见:Chapter 7. 内置函数 运算符 别名 语法示例 含义 ...

  3. PWN题搭建

    0x00.准备题目 例如:level.c #include <stdio.h> #include <unistd.h> int main(){ char buffer[0x10 ...

  4. PHP 腾讯云cos使用之我见

    因为某些人的原因,本文从新改名发布一遍. 原名称:tp5 -- 腾讯云cos简单使用 原文链接:https://www.cnblogs.com/YFYQ/p/10840050.html 因项目需要,本 ...

  5. word2vec 中的数学原理详解(二)预备知识

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/peghoty/article/details/37969635 https://blog.csdn. ...

  6. 欧拉函数φ(x)简要介绍及c++实现

    我还是很喜欢数论,从此吃喝不问,就此沉沦. 欧拉函数φ(x)的值为在[1,x)的区间内与x互质的数的个数 通式:    其中p1, p2……pn为x的所有质因数,x是不为0的整数.φ(1)=1. 注意 ...

  7. Linux系统状态检测

    基于Red Hat Enterprise Linux 7.5 1.ifconfig ifconfig用于获取和配置网络接口的网络参数,格式为“ifconfig [网络设备] [参数]” 参数: add ...

  8. 纯 CSS 创作一个表达怀念童年心情的条纹彩虹心特效

    效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/QxbmxJ 可交互视频教 ...

  9. 【php】Windows PHP及xdebug安装 安装

    php version 7.0 redis 下载地址 https://pecl.php.net/package/redis 7.0版本的redis不再依赖php_igbinary.dll扩展,可以独立 ...

  10. (转)UITextField

    //初始化textfield并设置位置及大小 UITextField *text = [[UITextField alloc]initWithFrame:CGRectMake(20, 20, 130, ...