「P5004」专心OI - 跳房子 解题报告

题面

把\(N\)个无色格子排成一行,选若干个格子染成黑色,要求每个黑色格子之间至少间隔\(M\)个格子,求方案数

思路:

矩阵加速

根据题面,这一题似乎可以用递推

设第\(i\)个格子的编号为\(i\),有\(i\)个格子时的方案数为\(f(i)\)

显然,当 \(i \le M+1\) 时,

可以所有格子不染色(方案数为\(1\)种,或者最多一个格子染色(方案数为\(i\)种)

所以有\(f(i)=i+1\)

当\(i>M+1\)时,

对于第\(i\)个格子可以由第\(i-1\)个格子转移过来,

而第\(i\)个格子有两种情况

1、不染色,显然可以这种情况下方案数为\(f(i-1)\)

2、染色,可以看出第\([i-m,i-1]\)个格子必定不染色,也就是没有贡献的,方案数为\(f(i-m-1)\)

但是!

\(N \le 10^{18}\),\(M \le 15\)

可以使用矩阵加速递推

求解

我们要记录的是应该是\(f(i) \to f(i+m)\)一共\(m+1\)个元素,于是就用一个\((M+1)^2\)的矩阵进行加速,配合快速幂求解

Code:

#include<bits/stdc++.h>
#define ll long long
#define Mod 1000000007
#define N 20
using namespace std;
int n;
ll b;
struct node{//矩阵放结构体里
    ll f[N][N];
}res,a;
node operator* (const node a,const node b)//重载*运算
{
    int i,j,k;
    node c;ll res;
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
        {
            res=0;
            for(k=0;k<n;k++)
                res=(res+a.f[i][k]*b.f[k][j])%Mod;
            c.f[i][j]=res;
        }
    return c;
}
void init(){//初始化
    int i;
    for(i=0;i<n;i++) res.f[0][i]=i+2;//矩阵下标从0开始,所以+2
    for(i=0;i<n-1;i++) a.f[i+1][i]=1;
    a.f[n-1][n-1]=a.f[0][n-1]=1;
}
void quickPow(ll b)
{
    while(b)
    {
        if(b&1) res=res*a;
        b>>=1;a=a*a;
    }
}
int main()
{
    scanf("%lld%d",&b,&n);--b,++n;//res初始为b=1的情况,所以实际的b要-1
    init();quickPow(b);//n++是方便计算间隔
    printf("%lld",res.f[0][0]);
    return 0;
}

原文地址:https://www.cnblogs.com/hovny/p/10415275.html

时间: 2024-11-09 05:17:49

「P5004」专心OI - 跳房子 解题报告的相关文章

「USACO08JAN」电话线Telephone Lines 解题报告

题面 大意:在加权无向图上求出一条从 \(1\) 号结点到 \(N\) 号结点的路径,使路径上第 \(K + 1\) 大的边权尽量小. 思路: 由于我们只能直接求最短路,不能记录过程中的具体的边--那样会特别麻烦 所以,我们就尝试着去想更优的办法 题目中所说,能够免去 \(K\) 条边的费用,那么对于要建设的边中,肯定免去费用最大 $K $ 条边更优 我们关注的应该是第 \(K+1\) 大边的边权,因为其他边权大于这条边边权的边都会被略去 这条边可以枚举吗? 似乎不行,枚举的复杂度还要在最短路的

[luogu5004]专心OI - 跳房子

传送门:https://www.luogu.org/problemnew/show/P5004 分析 动态规划转移方程是这样的\(f[i]=\sum^{i-m-1}_{j=0}f[j]\). 那么很明显的是要构造举证,而且要维护前缀和,所以需要保留\(m+1\)项. ac代码 #include <bits/stdc++.h> #define ll long long #define ms(a, b) memset(a, b, sizeof(a)) #define inf 0x3f3f3f3f

「csp校内训练 2019-10-24」解题报告

「csp校内训练 2019-10-24」解题报告 T1.猴猴吃苹果 \(Description\) 猴猴最喜欢在树上玩耍,一天猴猴又跳上了一棵树,这棵树有 \(N \ (N \leq 50000)\) 个苹果,每个苹果有一个编号,分别为 \(0\) ~ \(N - 1\) 它们之间由 \(N-1\) 个树枝相连,猴猴可以从树枝的一端爬到树枝的另一端,所以猴猴可以从任意一个苹果的位置出发爬到任意猴猴想去的苹果的位置. 猴猴开始在编号为 \(K \ (K < N)\) 的苹果的位置,并且把这个苹果吃

「csp校内训练 2019-10-30」解题报告

「csp校内训练 2019-10-30」解题报告 T1.树 题目链接(逃) \(Description\): 现在有一棵树,共 \(N\) 个节点. 规定:根节点为 \(1\) 号节点,且每个节点有一个点权. 现在,有 \(M\) 个操作需要在树上完成,每次操作为下列三种之一: \(1 \ x \ a\):操作 \(1\),将节点 \(x\) 点权增加 \(a\). \(2 \ x \ a\):操作 \(2\),将以节点 \(x\) 为根的子树中所有点的权值增加 \(a\). \(3 \ x\)

tyvj P2018 「Nescaf&#233;26」小猫爬山 解题报告

P2018 「Nescafé26」小猫爬山 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 Freda和rainbow饲养了N只小猫,这天,小猫们要去爬山.经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了(呜咕>_<). 描述 Freda和rainbow只好花钱让它们坐索道下山.索道上的缆车最大承重量为W,而N只小猫的重量分别是C1.C2……CN.当然,每辆缆车上的小猫的重量之和不能超过W.每租用一辆缆车,Freda和rainb

「JLOI2015」管道连接 解题报告

「JLOI2015」管道连接 先按照斯坦纳树求一个 然后合并成斯坦纳森林 直接枚举树的集合再dp一下就好了 Code: #include <cstdio> #include <cctype> #include <cstring> #include <algorithm> using std::min; const int N=1<<10; template <class T> void read(T &x) { x=0;cha

解题报告 之 2015蓝桥杯 垒骰子

解题报告 之 2015蓝桥杯 垒骰子 赌圣 atm 晚年迷恋上了垒骰子,就是把骰子一个垒在还有一个上边.不能歪歪扭扭,要垒成方柱体. 经过长期观察,atm 发现了稳定骰子的奥秘:有些数字的面贴着会互相排斥! 我们先来规范一下骰子:1 的对面是 4.2 的对面是 5,3 的对面是 6. 如果有 m 组相互排斥现象,每组中的那两个数字的面紧贴在一起,骰子就不能稳定的垒起来. atm 想计算一下有多少种不同的可能的垒骰子方式. 两种垒骰子方式同样,当且仅当这两种方式中相应高度的骰子的相应数字的朝向都同

「WC2016」论战捆竹竿

「WC2016」论战捆竹竿 前置知识 参考资料:<论战捆竹竿解题报告-王鉴浩>,<字符串算法选讲-金策>. Border&Period 若前缀 \(pre(s,x)?\) 与后缀 \(suf(s,n-x-1)?\) 相等,则 \(pre(s, x)?\) 是 \(s?\) 的一个 \(\text{Border}?\). \(x?\) 是 \(s?\) 的一个周期 (\(\text{Preiod}?\)) 满足 \(s[i]=s[i+x],\forall{1\leq i\le

大数据和「数据挖掘」是何关系?---来自知乎

知乎用户,互联网 244 人赞同 在我读数据挖掘方向研究生的时候:如果要描述数据量非常大,我们用Massive Data(海量数据)如果要描述数据非常多样,我们用Heterogeneous Data(异构数据)如果要描述数据既多样,又量大,我们用Massive Heterogeneous Data(海量异构数据)--如果要申请基金忽悠一笔钱,我们用Big Data(大数据) 编辑于 2014-02-2817 条评论感谢 收藏没有帮助举报作者保留权利 刘知远,NLPer 4 人赞同 我觉得 大数据