热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

洛谷P3758[TJOI2017]可乐(DP||矩阵优化)

题目链接:https:www.luogu.com.cnproblemP3758 在不用矩阵优化之前,可以写递推记忆化:1#include2#include

题目链接:https://www.luogu.com.cn/problem/P3758

 

在不用矩阵优化之前,可以写递推/记忆化:


1 #include
2 #include
3 #include
4 using namespace std;
5 const int N=35;
6 const int maxn=1e6+5;
7 const int mod=2017;
8 int n,m,ans,t;
9 int dp[N][maxn];
10 int head[N],tot;
11 struct node{
12 int to,next;
13 }edge[N<<1];
14 void add(int u,int v){
15 edge[tot].to=v;
16 edge[tot].next=head[u];
17 head[u]=tot++;
18 }
19 int DFS(int u,int t,int f){
20 if(dp[u][t]) return dp[u][t];
21 if(t==1) return 1;
22 dp[u][t]=1;
23 for(int i=head[u];i!=-1;i=edge[i].next){
24 int v=edge[i].to;
25 dp[u][t]+=DFS(v,t-1,u);
26 dp[u][t]%=mod;
27 }
28 dp[u][t]+=DFS(u,t-1,f);
29 dp[u][t]%=mod;
30 return dp[u][t];
31 }
32 int main(){
33 memset(head,-1,sizeof(head));
34 scanf("%d%d",&n,&m);
35 for(int i=1;i<=m;i++){
36 int u,v;
37 scanf("%d%d",&u,&v);
38 add(u,v);
39 add(v,u);
40 }
41 scanf("%d",&t);
42 printf("%d",DFS(1,t+1,0));
43 return 0;
44 }
AC代码

 

然而这道题可以用矩阵快速幂优化:

用邻接矩阵存图,那么这恰好就是一个矩阵A,矩阵的应用可以求有向图中从a到b经过k条边的可能数。

那么经过t次矩阵乘法,即$A^t$,然后$ans=\sum\limits_{i=0}^n a[1][i]$

(其中b为单元矩阵,即对角线为1,其余为0的矩阵,相当于普通的“1”。)

 

AC代码:


1 #include
2 #include
3 #include
4 using namespace std;
5 int n,m,t,sum;
6 const int mod=2017;
7 struct Mat{
8 int mat[31][31];
9 Mat(){
10 memset(mat,0,sizeof(mat));
11 }
12 Mat operator*(const Mat &self)const{
13 Mat ans;
14 for(int i=0;i<=30;i++)
15 for(int j=0;j<=30;j++)
16 for(int k=0;k<=30;k++)
17 (ans.mat[i][j]+=mat[i][k]*self.mat[k][j])%=mod;
18 return ans;
19 }
20 }a,b;
21 void init(){
22 for(int i=0;i<=30;i++) b.mat[i][i]=1;//b为单位矩阵
23 }
24 void ksm(int n){
25 while(n){
26 if(n&1) b=b*a;
27 a=a*a;
28 n>>=1;
29 }
30 }
31 int main(){
32 scanf("%d%d",&n,&m);
33 for(int i=1;i<=m;i++){
34 int u,v;
35 scanf("%d%d",&u,&v);
36 a.mat[u][v]=a.mat[v][u]=1;
37 }
38 for(int i=0;i<=n;i++) { a.mat[i][0]=1; a.mat[i][i]=1;}
39 scanf("%d",&t);
40 init();
41 ksm(t);
42 for(int i=0;i<=n;i++) (sum+=b.mat[1][i])%=mod;
43 printf("%d\n",sum);
44 return 0;
45 }
AC代码

 



推荐阅读
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • c语言\n不换行,c语言printf不换行
    本文目录一览:1、C语言不换行输入2、c语言的 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 本文介绍了最长上升子序列问题的一个变种解法,通过记录拐点的位置,将问题拆分为左右两个LIS问题。详细讲解了算法的实现过程,并给出了相应的代码。 ... [详细]
  • 浏览器中的异常检测算法及其在深度学习中的应用
    本文介绍了在浏览器中进行异常检测的算法,包括统计学方法和机器学习方法,并探讨了异常检测在深度学习中的应用。异常检测在金融领域的信用卡欺诈、企业安全领域的非法入侵、IT运维中的设备维护时间点预测等方面具有广泛的应用。通过使用TensorFlow.js进行异常检测,可以实现对单变量和多变量异常的检测。统计学方法通过估计数据的分布概率来计算数据点的异常概率,而机器学习方法则通过训练数据来建立异常检测模型。 ... [详细]
author-avatar
迪迪
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有