首先这是一道计数类DP,那我们得先推式子,经过瞎掰乱凑,经过认真分析,我们可以得到这样的方程

F(N)=F(0)+F(1)+....+F(N-M-1)

所有F初值为1,F(1)=2

ANS=F(N+M);

那显然我们有这样的代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 const int M=1e9+7;
 6 using namespace std;
 7 inline int read(){
 8     char chr=getchar();    int f=1,ans=0;
 9     while(!isdigit(chr)) {if(chr=='-') f=-1;chr=getchar();}
10     while(isdigit(chr))  {ans=(ans<<3)+(ans<<1);ans+=chr-'0';chr=getchar();}
11     return ans*f;
12 }
13 void write(int x){
14     if(x<0) putchar('-'),x=-x;
15     if(x>9) write(x/10);
16     putchar(x%10+'0');
17 }int n,m,f[10000005];
18 int main(){
19     n=read(),m=read();
20     f[0]=1;f[1]=2;
21     for(int i=1;i<=n+m;i++){
22         f[i]=1;
23         for(int j=0;j<=i-m-1;j++)
24             if(f[i]+f[j]>M) f[i]=f[i]+f[j]-M;
25             else f[i]=f[i]+f[j];//卡一波时间
26     }cout<<f[n+m];
27     return 0;
28 }

显然这是O(n^2)的算法,然而面对N=1e18,这个算法可以去优化见鬼了,这样子由于语句比较简单,勉强可以过十万的数据大概30分

考虑优化:

我们先看一下上面的式子,尝试对这个式子变形...好吧,其实就是迭代,然后用鸽笼原理一通乱搞:

F(N)=F(N-1)+F(N-M-1)

ANS=F(N)

好了我们把这个东西优化得到了O(N)的算法:

期望得分:50pts

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 const int M=1e9+7;
 6 using namespace std;
 7 inline int read(){
 8     char chr=getchar();    int f=1,ans=0;
 9     while(!isdigit(chr)) {if(chr=='-') f=-1;chr=getchar();}
10     while(isdigit(chr))  {ans=(ans<<3)+(ans<<1);ans+=chr-'0';chr=getchar();}
11     return ans*f;
12 }
13 void write(int x){
14     if(x<0) putchar('-'),x=-x;
15     if(x>9) write(x/10);
16     putchar(x%10+'0');
17 }int n,m,f[10000005];
18 int main(){
19     n=read(),m=read();
20     f[0]=1;f[1]=2;
21     for(int i=2;i<=n;i++)
22         f[i]=(f[i-1]+f[max(i-m-1,0)])%M;
23     cout<<f[n];
24     return 0;
25 }

考虑继续优化

某个大佬说过1e18的数据考虑logn的算法,比如快速幂。

这既然是DP,那自然往矩阵乘法考虑。

  考虑构造矩阵:m这么小,而且递推式中出现的常量只有m,显然矩阵的大小要往m*m考虑

  m=1的时候斐波那契,显然不用我推了

  看一下其他情况:

  

得到通式(写了的是1,其他是0):

然后会矩阵加速的同学都知道该怎么做了吧...

 1 // luogu-judger-enable-o2
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<algorithm>
 6 #define int long long
 7 const int M=1e9+7;
 8 using namespace std;
 9 inline int read(){
10     char chr=getchar();    int f=1,ans=0;
11     while(!isdigit(chr)) {if(chr=='-') f=-1;chr=getchar();}
12     while(isdigit(chr))  {ans=(ans<<3)+(ans<<1);ans+=chr-'0';chr=getchar();}
13     return ans*f;
14 }
15 void write(int x){
16     if(x<0) putchar('-'),x=-x;
17     if(x>9) write(x/10);
18     putchar(x%10+'0');
19 }int n,m;
20 struct P{int a[20][20];P(){memset(a,0,sizeof(a));}}A,B;
21 P operator *(const P &x,const P &y){
22     P ans;
23     for(int i=0;i<m;i++)
24         for(int k=0;k<m;k++)
25             for(int j=0;j<m;j++)
26                 ans.a[i][j]=(ans.a[i][j]+x.a[i][k]*y.a[k][j])%M;
27     return ans;
28 }
29 void KSM(int n){
30     while(n){
31         if(n&1) B=B*A;
32         n>>=1;A=A*A;
33     }
34 }
35 inline void init(){
36     n=read(),m=read();--n,++m;
37     A.a[m-1][m-1]=A.a[0][m-1]=1;
38     for(int i=0;i<m-1;i++)    A.a[i+1][i]=1;//初始矩阵
39     for(int i=0;i<m;i++)B.a[0][i]=i+2;
40 }
41 signed main(){
42     init();KSM(n);
43     write(B.a[0][0]);
44     return 0;
45 }

转载于:https://www.cnblogs.com/zhenglw/p/10437703.html

【LuoguP5004】 专心OI - 跳房子相关推荐

  1. [luogu5004]专心OI - 跳房子【矩阵加速+动态规划】

    传送门:https://www.luogu.org/problemnew/show/P5004 分析 动态规划转移方程是这样的\(f[i]=\sum^{i-m-1}_{j=0}f[j]\). 那么很明 ...

  2. P5004-专心OI - 跳房子【dp,矩阵乘法】

    正题 题目链接:https://www.luogu.org/problemnew/show/P5004 题目大意 把NNN个无色格子排成一行,可以把某些格子染成黑色,但两个黑色格子之间必须至少有MMM ...

  3. 雨季花月,回忆似金。登轼高望,志在远方。【记妙妙的OI生涯】

    一 "你觉得今天下午的信息编程课有兴趣吗"爸爸问我. "有啊,看起来很厉害的样子啊!" "那就好好学哦,听说对升学很有帮助." " ...

  4. OI退役记,第九部分,过去和现在

    您要去斯卡布罗的集市吗? 欧芹,鼠尾草,迷迭香和百里香. 代我向那里的一个人问好, 如果他曾经是我的爱人. 让他为我做一件麻布衬衫: 欧芹,鼠尾草,迷迭香和百里香. 不要有针眼或缝线的痕迹, 那他才是 ...

  5. NOIP2017游记兼OI半程回忆录

    没办法 我是一个矫情的人 前言 一瞬间感觉自己好像挺惨的 哪怕是共同在一个教室数月的同学 也基本上都是从初中开始接触的OI的 最次的也都有些基本的了解 而我在去年十月之前 基本上连个屁都不知道 也就会 ...

  6. Noip2017 跳房子——普及组

    原题地址(点我) 题目描述 跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一. 跳房子的游戏规则如下: 在地面上确定一个起点,然后在起点右侧画 n 个格子,这些格子都在同一条 ...

  7. OI基础系列之最大子数组问题

    OI基础系列之最大子数组问题   --Edward2414    oi退役了,虽然没取得多少成绩,也算是走过一会的人了.我相信绝大多数oi党都是自学成才,在此,我感谢那些把自己所学写到博客里的前辈们, ...

  8. 【解题报告系列】超高质量题单 + 题解(ACM / OI)超高质量题解

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我新写的超高质量的题解和代码,题目难度不 ...

  9. 《算法竞赛中的初等数论》(五)正文 0x50筛法(ACM / OI / MO)(十五万字符数论书)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 写在最前面:本文部分内容来自网上各大博客或是各类图书,由我个人整理,增加些许见解,仅做学习交流使用,无 ...

最新文章

  1. HDU6964 I love counting (字典树+莫队)
  2. Arduino可穿戴教程之第一个程序——上传运行程序(四)
  3. landmark如何恢复oracle,LandmarkR5000数据迁移方法及迁移常见问题(带图解)
  4. JAVA运行程序代码段
  5. UE4异步编程专题 - TFunction
  6. 中国IT行业盛行,互联网行业早已饱和!程序员“过多”是主要原因?
  7. Jenkins Gitee 实现持续集成CI/CD工具【免费、推荐】
  8. PHP笔记-Smarty模板引擎的使用
  9. bci测试如何整改_EMC测试不合格,应该这样整改
  10. mysql表的一列拆分成两列_将float值拆分成MySQL表的两列?
  11. OpenGL超级宝典(第7版)之清单的初始环境配置VS2019
  12. 基于数字孪生的IBV智能建筑可视化系统了解一下
  13. 物联网嵌入式STM32资料大全,超100G
  14. 利用matlab实现AM调制解调
  15. 高质量 Go 进阶图书,它来了
  16. python:初识自动化测试 playwright 库
  17. 男程序员写代码的样子 VS 女程序员写代码的样子
  18. FFmpeg命令行工具-实用命令
  19. Android入门教程 Android开发环境搭建【详细教程】
  20. 学习笔记-----浅谈汇编指令CMP运行机制

热门文章

  1. Hive 导数据到本地(2种方式)
  2. Django的get和post请求处理
  3. java statement 参数_java statement详细用法
  4. AdaptiveMaxPool的作用
  5. leetcode —— 1282. 用户分组
  6. Scrapy网络爬虫实战[保存为Json文件及存储到mysql数据库]
  7. matlab绘3d图
  8. Java 8实现BASE64编解码
  9. kd树介绍(KNN算法引出)
  10. 机器学习笔记III: 基于支持向量机的分类预测