D:上楼梯【2019北大夏令营D】找不到提交入口正确性未知
-
总时间限制:
1000ms
-
内存限制:
128kB
-
描述
小S在玩一个叫上楼梯的游戏。楼梯一共有n层台阶。因为腿长的限制,小S每次最多只能上k层台阶。小S是一个迷信的人,所以他不希望自己某一步走的步数的数字里有"4",(比如4,14,44都含有数字"4")。现在,小S想要知道,有多少种走完这n层台阶的方案?
-
输入
输入包含多组数据。 每组数据第一行输入一个整数 n, k(1 <= k <= n <= 50)。 输入以 n,k=0 结束。
-
输出
对于每组数据,输出一行一个整数,表示答案。
-
样例输入
10 1 10 2 18 8 0 0
-
样例输出
1 89 71262
-
提示
注意答案可能超过 int 所能表示的范围,请谨慎选择存储答案以及中间数据的数据类型。
题解
-
递推关系(子问题的解构造问题的解):dp[i]=以[i-k,i-1]级台阶为倒数第二个目的地的方案数之和
-
先走到倒数第二个目的地,然后一步走到终点
-
-
初始:dp[0],不上台阶,=1
#define MAXN 55
long long dp[MAXN];
vector<int>step_bank,step;
int main()
{
//1<=k<=50, must be <=2 digit
for(int i=1; i<=MAXN; ++i){
if(i%10!=4 && i/10!=4){
step_bank.push_back(i);
}
}
int n,k;
long long ans;
while(cin>>n>>k && (n||k)){
step.clear();
dp[0]=1;
for(int stp:step_bank){
if(stp>k) break;
step.push_back(stp);
}
for(int i=1; i<=n; ++i){
ans=0;
for(int stp:step){
if(i-stp>=0){
ans+=dp[i-stp];
}
}
dp[i]=ans;
}
cout<<dp[n]<<endl;
}
return 0;
}