HDU 2157 How many ways??(简单线性DP | | 矩阵快速幂)
2016-04-21 09:03
555 查看
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=2157
这道题目很多人的题解都是矩阵快速幂写的,矩阵快速幂倒是麻烦了许多了。先给DP的方法
dp[i][j] 表示走过了i个点到了j点的步数
矩阵快速幂的方法也很好理解。把这个图用邻接矩阵A表示,A(i,j)=1表示从i到j有一条路,让C=A*A C(i,j)=sum{A(i,k)*A(k,j)} 表示从i到j经过2个点的路径数,所以经过几个点,就是求矩阵A的几次方。
效率比DP要低
http://acm.hdu.edu.cn/showproblem.php?pid=2157
这道题目很多人的题解都是矩阵快速幂写的,矩阵快速幂倒是麻烦了许多了。先给DP的方法
dp[i][j] 表示走过了i个点到了j点的步数
#include <iostream> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <algorithm> #include <math.h> using namespace std; const int mod=1000; int n,m; int a[25][25]; int dp[25][25]; int t; int main() { int x,y,k; while(scanf("%d%d",&n,&m)!=EOF) { if(n==0&&m==0) break; memset(a,0,sizeof(a)); for(int i=1;i<=m;i++) { scanf("%d%d",&x,&y); a[x][y]=1; } scanf("%d",&t); while(t--) { scanf("%d%d%d",&x,&y,&k); memset(dp,0,sizeof(dp)); dp[1][x]=1; for(int i=2;i<=k+1;i++) { for(int j=0;j<n;j++) { for(int p=0;p<n;p++) { if(p==j) continue; if(dp[i-1][p]!=0&&a[p][j]==1) (dp[i][j]+=(dp[i-1][p])%mod)%=mod; } } } printf("%d\n",dp[k+1][y]); } } return 0; }
矩阵快速幂的方法也很好理解。把这个图用邻接矩阵A表示,A(i,j)=1表示从i到j有一条路,让C=A*A C(i,j)=sum{A(i,k)*A(k,j)} 表示从i到j经过2个点的路径数,所以经过几个点,就是求矩阵A的几次方。
效率比DP要低
#include <iostream> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <algorithm> #include <math.h> using namespace std; const int mod=1000; struct Node { int a[25][25]; }; int n,m,x,y,k,t; Node multiply(Node a,Node b) { Node c; memset(c.a,0,sizeof(c.a)); for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { if(!a.a[i][j]) continue; for(int k=0;k<n;k++) { (c.a[i][k]+=(a.a[i][j]*b.a[j][k])%mod)%=mod; } } } return c; } Node get(Node a,int x) { Node c; memset(c.a,0,sizeof(c.a)); for(int i=0;i<n;i++) c.a[i][i]=1; for(x;x;x>>=1) { if(x&1) c=multiply(c,a); a=multiply(a,a); } return c; } int main() { while(scanf("%d%d",&n,&m)!=EOF) { if(n==0&&m==0) break; Node a; memset(a.a,0,sizeof(a.a)); for(int i=1;i<=m;i++) { scanf("%d%d",&x,&y); a.a[x][y]=1; } scanf("%d",&t); Node c; while(t--) { c=a; scanf("%d%d%d",&x,&y,&k); c=get(c,k); printf("%d\n",c.a[x][y]); } } }
相关文章推荐
- DataGridView DataGridViewCheckBoxColumn编辑时实时触发事件
- 第八周【项目2-用对象数组操作长方柱类】
- Live555研究之一 源代码编译
- C++实验4-循环求和
- HDU 2157 How many ways??(简单线性DP | | 矩阵快速幂)
- php.ini memory_limit引起的问题
- Working with Typography
- l两点之间的距离--线段类
- 第八周项目1--数组做数据成员(2)
- bzoj 2730: [HNOI2012]矿场搭建 dfs
- 一个界面,有多个UITextField的时候,点击提交按钮发送数据时,取消键盘
- 常用SQL语句
- 第四次实验
- 滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(4月21日)
- HDU 4031 Attack
- python psutil 进行系统管理 no.1
- 无废话ExtJs 入门教程四[表单:FormPanel]
- Spring MVC 流程图
- jquery实现侧边栏左右伸缩
- 第七周上机实践项目 项目1-成员函数,友元函数,和一般函数的区别(2)