Codeforce821E Okabe and El Psy Kongroo
题意:给n条水平线段点终点高度,只能右上方向走,向右走,右下方向走,只能在第一象限及坐标轴上线段下面运动问到(K,0)有多少种方案
题解:可以推出DP式子,对每一条线段使用快速幂
#include <bits/stdc++.h> #define maxn 20 using namespace std; long long mod = 1e9+7, len=20, n, k, sta[110], en[110], c[110]; struct mat{ long long m[maxn][maxn];//注意初始化 mat friend operator*(mat a,mat b){ mat d; memset(d.m, 0, sizeof(d.m)); for(int i=0;i<len;i++) for(int j=0;j<len;j++) for(int k=0;k<len;k++) d.m[i][j] = (d.m[i][j]%mod+(a.m[i][k]*b.m[k][j])%mod)%mod; return d; } }; mat f(mat x,long long num){ mat t; memset(t.m, 0, sizeof(t.m)); for(int i=0;i<len;i++) t.m[i][i] = 1; while(num){ if(num&1) t = t*x; x = x*x; num >>= 1; } return t; } int main(){ int i,j; mat s, ss; memset(s.m, 0, sizeof(s.m)); memset(ss.m, 0, sizeof(ss.m)); s.m[0][0] = 1; for(i=0;i<len;i++) for(j=i-1;j<=i+1;j++) if(j>=0&&j<len) ss.m[i][j] = 1; cin>>n>>k; for(i=0;i<n;i++) cin>>sta[i]>>en[i]>>c[i]; i = 0; while(i<n&&k>=en[i]){ len = c[i]+1; s = s*f(ss, en[i]-sta[i]); i++; } len = c[i]+1; s = s*f(ss, k-en[i-1]); cout<<s.m[0][0]<<endl; return 0; }
posted on 2017-07-01 16:47 2855669158 阅读(336) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步