题意

如果一个 \(1\to N\) 的排列 \(P=[P_1, P_2, ... P_N]\) 中的任意元素 \(P_i\) 都满足 \(|P_i-i| ≤ K\) ,我们就称 \(P\) 是 \(K\)-偏差排列。
给定 \(N\) 和 \(K\) ,请你计算一共有少个不同的排列是 \(K\)-偏差排列。
例如对于 \(N=3\) ,有 \(3\) 个 \(1\)-偏差排列:\([1, 2, 3], [1, 3, 2], [2, 1, 3]\)。
由于答案可能非常大,你只需要输出答案模 \(1000000007\) 的余数。
对于 \(70\%\) 的数据,\(1 ≤ N ≤ 1000\)
对于 \(100\%\) 的数据,\(1 ≤ N ≤ 1000000000, 1 ≤ K ≤ 3\)

题解

一道好题~
这是它的最初版本 #1732 : 1-偏差排列 .
那个找规律就是 斐波那契数列 了, dp 的话也是一样的结果 .

对于这个题我们可以沿用那题思路, 考虑一个位置 \(i\) 能放哪些数, 根据定义能放 \([i-k, i+k]\) 中共 \(2k+1\) 个数.
考虑状压到 \(i\) 这个点, 这些数中的哪些被放了, 每次转移的时候考虑放入一个数, 这个数之前不能出现, 这样就是合法转移了.
最后到 \(n\) 的时候, 不能放比 \(n\) 大的数, 且小于等于 \(n\) 的数都要放进去, 只会有那个位置存在正确答案, 这个状态 \(sta=2 ^ {k + 1} - 1\) (也就是意味着 \([n - k, n]\)都得选) .
当 \(n < k\) 的时候要特判掉一些诡异的特殊情况 .

然后这样直接写就有 \(70pts\) 了.
有一些不合法状态不能转移, 也就是要放的数不存在于 \([1, n]\) 之间.

这样的话, 就是矩阵快速幂套路优化了, 考虑对这个转移系数建立矩阵, 然后它的 \(n\) 次幂中的 \((sta,sta)\) 这个位置就会存在最后的答案咯...

代码

\(70pts:\)

#include <bits/stdc++.h>
#define For(i, l, r) for(register int i = (l), i##end = (int)(r); i <= i##end; ++i)
using namespace std;typedef long long ll;const ll Mod = 1e9 + 7;int n, k, all;
ll ans = 0, dp[2][1500] = {0};int main () {cin >> n >> k;if (n <= 2) return printf ("%d\n", n), 0;all = (1 << (2 * k + 1)) - 1;dp[0][0] = 1;int cur = 0;For (i, 1, n) {For (j, 0, all) if(dp[cur][j]) {int sta = (j >> 1);For (s, 0, 2 * k) if (!(sta & (1 << s))) {int tmp = i - k + s;if (tmp < 1 || tmp > n) continue ;(dp[cur ^ 1][sta | (1 << s)] += dp[cur][j]) %= Mod;}dp[cur][j] = 0;}cur ^= 1;}int Sta = (1 << (k + 1)) - 1;printf ("%lld\n", dp[cur][Sta]);return 0;
}

\(100pts:\)

#include <bits/stdc++.h>
#define For(i, l, r) for(register int i = (l), i##end = (int)(r); i <= i##end; ++i)
#define Set(a, v) memset(a, v, sizeof(a))
using namespace std;void File() {
#ifdef zjp_shadowfreopen ("P1743.in", "r", stdin);freopen ("P1743.out", "w", stdout);
#endif
}const int Mod = 1e9 + 7, Maxn = 130;int n, k, all;struct Matrix {int a[Maxn][Maxn]; Matrix() { Set(a, 0); }void Unit() { For (i, 0, all) a[i][i] = 1; }
};inline Matrix operator * (Matrix a, Matrix b) {Matrix res;For (i, 0, all) For (k, 0, all) if (a.a[i][k])For (j, 0, all) (res.a[i][j] += 1ll * a.a[i][k] * b.a[k][j] % Mod) %= Mod;return res;
}inline Matrix fpm(Matrix x, int power) {Matrix res; res.Unit();for (; power; power >>= 1, x = x * x)if (power & 1) res = res * x;return res;
}Matrix Bas, Ans;int ans = 0;int main () {File();cin >> n >> k;if (n <= 2) return printf ("%d\n", n), 0;all = (1 << (2 * k + 1)) - 1;For (i, 0, all) {int j = (i >> 1);For (s, 0, 2 * k) if (!(j & (1 << s))) ++ Bas.a[i][j | (1 << s)];}Ans = fpm(Bas, n);int Sta = (1 << (k + 1)) - 1;printf ("%d\n", Ans.a[Sta][Sta]);return 0;
}

转载于:https://www.cnblogs.com/zjp-shadow/p/9042753.html

hihoCoder#1743:K-偏差排列(矩阵快速幂+状压dp)相关推荐

  1. 【Codeforces Gym - 101635C Macarons 】【矩阵快速幂+状压】【dfs时间换空间】

    [链接] http://codeforces.com/gym/101635/attachments [题意] 求用1*1,1*2的方格填n*m的矩阵的方法数 [知识点] 状压dfs+矩阵快速幂 [分析 ...

  2. [BZOJ5010][FJOI2017]矩阵填数(状压DP)

    5010: [Fjoi2017]矩阵填数 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 90  Solved: 45 [Submit][Status ...

  3. 线性代数 —— 矩阵快速幂

    [概述] 矩阵快速幂利用矩阵的乘法与整数快速幂的结合,能够快速的算出 n 阶方阵 A 的 M 次幂 A^b,其结果仍是一个矩阵,无具体含义,在信息学竞赛中,矩阵快速幂常用于求解线性递推关系. 关于矩阵 ...

  4. HDU 5863 cjj's string game ( 16年多校10 G 题、矩阵快速幂优化线性递推DP )

    题目链接 题意 : 有种不同的字符,每种字符有无限个,要求用这k种字符构造两个长度为n的字符串a和b,使得a串和b串的最长公共部分长度恰为m,问方案数 分析 : 直觉是DP 不过当时看到 n 很大.但 ...

  5. 矩阵快速幂以及其优化【华东交大课程】

    矩阵快速幂以及其优化[华东交大课程] 快速幂基础:C++快速幂_Kicamon的博客-CSDN博客 矩阵快速幂就是在快速幂的基础上结合矩阵运算的用法,其用途较为广泛,可以很大程度上优化代码. 一.矩阵 ...

  6. 2015多校10 1006.CRB and Puzzle HDU5411(邻接矩阵求k长路条数,矩阵快速幂

    题意:有若干字符,现在要把它们连成一个字符串,每种字符后面只能接特定种类的字符,现在询问能连接出的长度小于等于m的字符串有多少种. 思路:我们可以把这个转移关系看成一个图,如果字符a后面可以接b,那么 ...

  7. c语言求佩尔方程的解设计思路,c语言版 佩尔方程求最小正整数解及第k解(矩阵快速幂)...

    佩尔方程讲解连接: 若一个丢番图方程具有以下的形式: 且 为正整数,则称此方程为佩尔方程(英文:Pell's equation 德文:Pellsche Gleichung) 若 是完全平方数,则这个方 ...

  8. 沉默是金 矩阵快速幂

    沉默是金 时间限制: 1 Sec  内存限制: 128 MB 题目描述 终于活成了自己最讨厌的模样. 小希遇到了一个序列,他现在可以在序列中可以有重复地取k个数组成一个新的序列.该序列有以下几个性质: ...

  9. 斗地主(矩阵快速幂)

    地斗主 思路 看到这nnn非常大,感觉一定是个结论公式题,但是感觉又不像是排列组合,于是可以考虑矩阵快速幂了,所以关键就是得得到递推公式了. 我们将棋盘分成两部分n−num,numn - num, n ...

  10. AtCoder abc256全题解(区间合并模板、矩阵快速幂优化dp、线段树……)

    文章目录 A B C-枚举 D-区间合并模板 E-图论建模,函数图的性质 题意 思路 代码 F-树状数组 题意 思路 代码 G-矩阵快速幂优化dp H-线段树 思路 实现 传送门 本文CSDN 本文j ...

最新文章

  1. Numpy入门教程:09. 输入和输出
  2. et超排真正免狗能用版 真正好用的东西_真正合格小户型,收纳都特别能“装”...
  3. Python中的虚拟环境-virtualenv
  4. linux下c语言读取roed文件,如何在Linux系统上安装Android4.4.docx
  5. OpenShift 4 - 为Serivce Account赋权
  6. iOS基本UI元素示例教程
  7. C语言中整型常量的表达方式
  8. 知虾:2022 Shopee开店图文指南,手把手教你入驻
  9. quick cocos2dx 组件
  10. 有效集法(Active Set),内点法(Interior-Point)及序列二次规划(SQP)法
  11. 有道词典android wear,iOS版有道词典6.0发布!最好的全能翻译工具
  12. 使用Docker部署ShareLaTex并简单配置中文环境
  13. [渝粤教育] 西安交通大学 中国哲学经典著作导读 参考 资料
  14. ROS中使用protoBuf通信
  15. 【正点原子Linux连载】第三十五章 Linux内核顶层Makefile详解 -摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0
  16. 天长地久 (20分)
  17. 基于cefsharp的浏览器应用开发(支持XP系统)
  18. 黑苹果0x0501_黑苹果原版安装从零开始---3-clover配置篇
  19. 电信运营商基于 MQTT 协议 构建千万级 IoT 设备管理平台
  20. 如何在 Adob​e Photoshop 中制作拉伸的风景?

热门文章

  1. php dom对象,JavaScript_JavaScript DOM 对象深入了解,什么叫DOM,DOM是文档对象模型( - phpStudy...
  2. 『计算机视觉』Mask-RCNN_训练网络其一:数据集与Dataset类
  3. bsp 总结正规流程
  4. java面试之String的理解(自我理解)
  5. Linux 命令 -- tar
  6. 【转】随机函数 rand() srand() 以及seed的原理
  7. php写的仿爱帮网电话号码字符串处理(防采集)。
  8. android UI进阶之android中隐藏的layout 抽屉的运用
  9. vux和iview的弹出框总结
  10. LR监控linux系统资源