NC16546. 跳格子
描述
sum 个格子排成一排,每次可以往前跳 1-n 格,往回跳 1-m 格,而且在往回跳的时候只能跳在往前跳时踩过的格子。
输入描述
第一行一个数T,表示有T组数据
然后每组数据三个数 sum,n,m
输出描述
对于每组数据输出一个数表示答案
示例1
输入:
2 5 2 4 5 2 3
输出:
52 42
C++14(g++5.4) 解法, 执行用时: 162ms, 内存消耗: 3676K, 提交时间: 2018-06-09 11:01:55
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const long long P=233333333; const int N=4e5+89; long long f[28],g[N]; int main(){ int T,s,n,m; for(scanf("%d",&T);T--;){ scanf("%d%d%d",&s,&n,&m); f[0]=g[0]=1LL; for(int i=1;i<=m;++i) { f[i]=0; for(int j=i-1,k=1;j>=0&&k<=n;--j,++k){ f[i]=(f[i]+f[j])%P; } } for(int i=1;i<=s;++i) { g[i]=0; for(int j=1;j<=m&&j<=i;++j) { g[i]=(g[i]+f[j]*g[i-j]%P)%P; } } printf("%lld\n",g[s]); } }
C++11(clang++ 3.9) 解法, 执行用时: 120ms, 内存消耗: 3700K, 提交时间: 2020-05-14 10:57:41
#include<bits/stdc++.h> #define ll long long using namespace std; const ll p=233333333; ll t1,sum,n,m,i,j,a[500010],f[500010]; int main(){ scanf("%lld",&t1); while(t1--){ scanf("%lld%lld%lld",&sum,&n,&m); a[0]=f[0]=1; for(i=1;i<=m;i++){ a[i]=0; for(j=1;j<=min(i,n);j++)a[i]=(a[i]+a[i-j])%p; } for(i=1;i<=sum;i++){ f[i]=0; for(j=1;j<=min(m,i);j++)f[i]=(f[i]+f[i-j]*a[j])%p; } printf("%lld\n",f[sum]); } }