The first blood
HDU 2041 超级楼梯
Problem Description
有一楼梯共M级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第M级,共有多少种走法?
Input
输入数据首先包含一个整数N,表示测试实例的个数,然后是N行数据,每行包含一个整数M(1<=M<=40),表示楼梯的级数。
Output
对于每个测试实例,请输出不同走法的数量
Sample Input
2
2
3
Sample Output
1
2
思路:
有 i 个台阶的话 ,我可以先走1步剩下的情况就跟i-1的情况一样了,同理我还可以走2步剩下的情况就跟i-2步得一样了 因此 dp[i] = dp[i-1] + dp[i-2];
思路结束
AC code
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
ll dp[50];
void init(){
dp[1] = 1; dp[2] = 1;
for (int i = 3;i<50;i++) {
dp[i] = dp[i-1] +dp[i-2];
}
}
int main(){
init();
int t; cin>>t;
while(t--){
int n; scanf("%d",&n);
printf("%lld\n",dp[n]);
}
return 0;
}
The second blood
洛谷1192
题目描述
有 N级的台阶,你一开始在底部,每次可以向上迈最多 K 级台阶(最少 1 级),问到达第 N级台阶有多少种不同方式。
输入输出格式
输入格式:
两个正整数N,K。
输出格式:
一个正整数,为不同方式数,由于答案可能很大,你需要输出 ans mod 100003 后的结果。
输入输出样例
输入样例#1:
5 2
输出样例#1:
8
说明
对于 %20 的数据,有 N ≤ 10, K ≤ 3 ;
对于 %40 的数据,有 N ≤ 10000 ;
对于 %100 的数据,有 N ≤ 100000,K ≤ 100 。
stage\step | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
3 | 1 | 3 | 4 | 4 | 4 | 4 | 4 | 4 |
4 | 1 | 5 | 7 | 8 | 8 | 8 | 8 | 8 |
5 | 1 | 8 | 13 | 15 | 16 | 16 | 16 | 16 |
6 | 1 | 13 | 24 | 29 | 31 | 32 | 32 | 32 |
7 | 1 | 21 | 44 | 56 | 61 | 63 | 64 | 64 |
8 | 1 | 34 | 81 | 108 | 120 | 125 | 127 | 128 |
或许细心的小伙伴已经发现一些规律了,
如果步数为 1 那么情况数恒唯一。
如果步数大于台阶数情况为 ksm(2,n-1)
对于步数等于2的dp[i][2]=dp[i−1][2]+dp[i−2][2]
对
于
步
数
等
于
2
的
d
p
[
i
]
[
2
]
=
d
p
[
i
−
1
]
[
2
]
+
d
p
[
i
−
2
]
[
2
]
对于步数等于3的dp[i][3]=dp[i−1][3]+dp[i−2][3]+dp[i−3][3]
对
于
步
数
等
于
3
的
d
p
[
i
]
[
3
]
=
d
p
[
i
−
1
]
[
3
]
+
d
p
[
i
−
2
]
[
3
]
+
d
p
[
i
−
3
]
[
3
]
对于步数等于4的dp[i][4]=dp[i−1][4]+dp[i−2][4]+dp[i−3][4]+dp[i−4][4]
对
于
步
数
等
于
4
的
d
p
[
i
]
[
4
]
=
d
p
[
i
−
1
]
[
4
]
+
d
p
[
i
−
2
]
[
4
]
+
d
p
[
i
−
3
]
[
4
]
+
d
p
[
i
−
4
]
[
4
]
对于步数等于5的dp[i][5]=dp[i−1][5]+dp[i−2][5]+dp[i−3][3]+dp[i−4][5]+dp[i−5][5]
对
于
步
数
等
于
5
的
d
p
[
i
]
[
5
]
=
d
p
[
i
−
1
]
[
5
]
+
d
p
[
i
−
2
]
[
5
]
+
d
p
[
i
−
3
]
[
3
]
+
d
p
[
i
−
4
]
[
5
]
+
d
p
[
i
−
5
]
[
5
]
对于步数等于n的dp[i][n]=dp[i−1][n]+dp[i−2][n]......+dp[i−n][n] 对 于 步 数 等 于 n 的 d p [ i ] [ n ] = d p [ i − 1 ] [ n ] + d p [ i − 2 ] [ n ] . . . . . . + d p [ i − n ] [ n ]
其实也有道理你想想如果步数为 2 有 i 个台阶的话 ,我可以先走1不剩下的情况就跟i-1的情况一样了,同理我还可以走2步剩下的情况就跟i-2步得一样了 那么dp[i][2] = dp[i-1][2] + dp[i-2][2]
每次三步,四步,五步……n步也是一样
AC code
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll mod = 100003;
ll dp[100001][101];
ll ksm(ll a,ll b){
ll res = 1;
while(b){
if(b&1) res = res*a%mod;
b>>=1;
a = a*a%mod;
}
return res;
}
void init(){
for (int i = 1;i<=100000;i++) {
dp[i][1] = 1;
}
for (int i = 2;i<=100;i++) {
ll s = 0;
for (int j = 1;j<=100000;j++) {
if(i>j) { dp[j][i] = dp[j][i-1]; s = (s + dp[j][i]) % mod; }
else if(i == j) { dp[j][i] = ksm(2,j-1); s = (s + dp[j][i]) % mod; }
else {
dp[j][i] = s;
s = ((s + dp[j][i] - dp[j-i][i]) % mod + mod ) % mod;
}
}
}
}
int main(){
init();
ll n,k;
while(~scanf("%lld %lld",&n,&k))
{
printf("%lld\n",dp[n][k]);
}
return 0;
}