UVa 11651 Krypton Number System DP + 矩阵快速幂
题意:
有一个\(base(2 \leq base \leq 6)\)进制系统,这里面的数都是整数,不含前导0,相邻两个数字不相同。
而且每个数字有一个得分\(score(1 \leq score \leq 10^9)\),得分为 相邻两个数字之差的平方之和。
给出\(base\)和\(score\),求满足条件的整数的个数 \(mod \, 2^{32}\)。
分析:
首先考虑DP的做法:
设\(dp(i, j)\)表示满足当前分数为\(i\)最后一个数字是\(j\)的数字的个数。
递推就是枚举下一个数字\(k\),就有转移方程:
\(dp(i+d,k)=\sum dp(i, j)\),其中\(k \neq j\)且\(d=(k-j)^2\)。
这种方法的复杂度使\(O(base^2 \cdot score)\)的。
考虑矩阵优化:
因为状态转移中,能得到的最大分数是\((base-1)^2\),所以我们的转移矩阵只要保留前面\((base-1)^2\)个\(score\)的信息就行了。
用语言不方便表达,我举具体例子,
当\(base=3\)时,有如下转移:

上面9行很好理解,就是一个错位。
下面3行才是状态的转移。
容易看出,我们的矩阵的边长最大会达到\(6(6-1)^2=150\)。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef unsigned int LL;
const int maxn = 150;
int n, m, sz;
struct Matrix
{
LL a[maxn][maxn];
Matrix() {
for(int i = 0; i < maxn; i++)
for(int j = 0; j < maxn; j++) a[i][j] = 0;
}
Matrix operator * (const Matrix& t) const {
Matrix ans;
for(int i = 0; i < sz; i++)
for(int j = 0; j < sz; j++) if(a[i][j])
for(int k = 0; k < sz; k++)
ans.a[i][k] += a[i][j] * t.a[j][k];
return ans;
}
};
Matrix pow_mod(Matrix a, int n) {
Matrix ans;
for(int i = 0; i < sz; i++) ans.a[i][i] = 1;
while(n) {
if(n & 1) ans = ans * a;
a = a * a;
n >>= 1;
}
return ans;
}
LL a[maxn], dp[25][6];
int main()
{
int T; scanf("%d", &T);
for(int kase = 1; kase <= T; kase++) {
printf("Case %d: ", kase);
scanf("%d%d", &n, &m);
int N = (n - 1) * (n - 1) * n;
//DP
memset(dp, 0, sizeof(dp));
for(int i = 1; i < n; i++) dp[0][i] = 1;
for(int i = 0; i < (n - 1) * (n - 1); i++) {
for(int j = 0; j < n; j++) {
for(int k = 0; k < n; k++) {
int d = (k - j) * (k - j);
if(!d || i + d > (n - 1) * (n - 1)) continue;
dp[i + d][k] += dp[i][j];
}
}
}
if(m < (n - 1) * (n - 1)) {
LL ans = 0;
for(int i = 0; i < n; i++) ans += dp[m][i];
printf("%u\n", ans);
continue;
}
sz = N;
int s = (n - 1) * (n - 1);
for(int i = 0; i < (n - 1) * (n - 1); i++)
for(int j = 0; j < n; j++)
a[i * n + j] = dp[i][j];
Matrix M;
for(int i = n; i < N; i++) M.a[i - n][i] = 1;
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++) if(j != i) {
int d = (j - i) * (j - i);
M.a[N - n + i][n * (s - d) + j] = 1;
}
M = pow_mod(M, m - (n - 1) * (n - 1) + 1);
LL ans = 0;
for(int i = N - n; i < N; i++)
for(int j = 0; j < N; j++)
ans += M.a[i][j] * a[j];
printf("%u\n", ans);
}
return 0;
}
UVa 11651 Krypton Number System DP + 矩阵快速幂的更多相关文章
- bnuoj 34985 Elegant String DP+矩阵快速幂
题目链接:http://acm.bnu.edu.cn/bnuoj/problem_show.php?pid=34985 We define a kind of strings as elegant s ...
- HDU 5434 Peace small elephant 状压dp+矩阵快速幂
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5434 Peace small elephant Accepts: 38 Submissions: ...
- 【BZOJ】2004: [Hnoi2010]Bus 公交线路 状压DP+矩阵快速幂
[题意]n个点等距排列在长度为n-1的直线上,初始点1~k都有一辆公车,每辆公车都需要一些停靠点,每个点至多只能被一辆公车停靠,且每辆公车相邻两个停靠点的距离至多为p,所有公车最后会停在n-k+1~n ...
- 【BZOJ】4861: [Beijing2017]魔法咒语 AC自动机+DP+矩阵快速幂
[题意]给定n个原串和m个禁忌串,要求用原串集合能拼出的不含禁忌串且长度为L的串的数量.(60%)n,m<=50,L<=100.(40%)原串长度为1或2,L<=10^18. [算法 ...
- BZOJ5298 CQOI2018 交错序列 【DP+矩阵快速幂优化】*
BZOJ5298 CQOI2018 交错序列 [DP+矩阵快速幂优化] Description 我们称一个仅由0.1构成的序列为"交错序列",当且仅当序列中没有相邻的1(可以有相邻 ...
- Codeforces 621E Wet Shark and Block【dp + 矩阵快速幂】
题意: 有b个blocks,每个blocks都有n个相同的0~9的数字,如果从第一个block选1,从第二个block选2,那么就构成12,问对于给定的n,b有多少种构成方案使最后模x的余数为k. 分 ...
- codeforces E. Okabe and El Psy Kongroo(dp+矩阵快速幂)
题目链接:http://codeforces.com/contest/821/problem/E 题意:我们现在位于(0,0)处,目标是走到(K,0)处.每一次我们都可以从(x,y)走到(x+1,y- ...
- [BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂)
[BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂) 题面 阿申准备报名参加GT考试,准考证号为N位数X1X2-.Xn,他不希望准考证号上出现不吉利的数字.他的不吉利数学A ...
- POJ-3070Fibonacci(矩阵快速幂求Fibonacci数列) uva 10689 Yet another Number Sequence【矩阵快速幂】
典型的两道矩阵快速幂求斐波那契数列 POJ 那是 默认a=0,b=1 UVA 一般情况是 斐波那契f(n)=(n-1)次幂情况下的(ans.m[0][0] * b + ans.m[0][1] * a) ...
随机推荐
- Java 8特性尝鲜:新新IO
Java 8特性尝鲜:新新IO 在这个专题前面的文章中,我们已经看到,使用Java8的lambda表达式对现有的JDK1.2 I/O库的提升,主要是可以使用lambda表达式来构造java.io.Fi ...
- 获取jqGrid中选择的行的数据
下面可以获取选择一行的id,如果你选择多行,那下面的id是最后选择的行的id: var id=$(‘#gridTable’).jqGrid(‘getGridParam’,'selrow’); 如果想要 ...
- JSONModel 简单例子
// ProductModel.h // JSONModel // // Created by 张国锋 on 15/7/20. // Copyright (c) 2015年 张国锋. All righ ...
- mongodb集合的增删
1.创建集合 createCollection() 方法 MongoDB db.createCollection(name, options) 是用来创建集合. 语法: 基本的 createColle ...
- html的文档设置标记上(格式标记)4-5
<html> <head> <title>第四课的标题及第五课的标题</title> <meta charset="utf-8" ...
- Jenkins系列——使用Dashboard View分类展示作业
1.目标 创建的作业多了,在一个视图中展示多有不便.因此需要使用 Dashboard View 将作业按照后缀进行分类展示. 如下图,可以按照后缀添加CODE,TEST和OTHER视图. 2.环境说明 ...
- WinForm form属性
一.布局 Autostroll 控件内容大于可见区域是否自动显示滚动条 Maximumsize 窗体可调到最大尺寸 minimumsize 窗体可调到最小尺寸 size 窗体看到的尺寸 Sta ...
- LibreOJ #107. 维护全序集
内存限制:256 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 上传者: 匿名 splay模板题 屠龙宝刀点击就送 #include <cstdio&g ...
- Caused by: java.lang.ClassNotFoundException: org.springframework.web.socket.server.standard.ServerEndpointExporter
Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/web/socket/ ...
- SAP Cloud for Customer客户主数据的重复检查-Levenshtein算法
SAP C4C的客户主数据创建时的重复检查,基于底层HANA数据库的模糊查找功能,根据扫描数据库中已有的数据检测出当前正在创建的客户主数据是否和数据库中记录有重复. 在系统里开启重复检查的配置: 在此 ...