枚举和模拟
07 递推数列
描述
给定 a0,a1以及 an=p×a(n−1)+q×(an−2) 中的 p,q
这里 n≥2
求第 k 个数 ak 对 10000 的模。
输入格式
输入包括 55 个整数:a0、a1、p、q、k
输出格式
第 k 个数 ak 对 10000 的模。
数据范围
1≤a0,a1,p,q,k≤10000
输入样例
20 1 1 14 5
输出样例
8359
解答
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
using namespace std;
//原始版 超时了 因为每一次都是实打实算的
long Digui(int a0, int a1, int p, int q, int k) {
//a0和a1是常数
if (k == 0) {
return a0;
}
if (k == 1) {
return a1;
}
//an=p×a(n−1)+q×(an−2)
return((p * Digui(a0, a1, p, q, k - 1) + q * Digui(a0, a1, p, q, k - 2))%10000);
}
//改进版 已经计算过的值 可以保存下来 而不必每一次都从头算
long Digui2(int a0, int a1, int p, int q, int k) {
static long memo[10000] = {0}; // 创建一个备忘录数组
if (k == 0) {
return a0;
}
if (k == 1) {
return a1;
}
if (memo[k] != 0) { // 如果备忘录中已经计算过该值,直接返回结果
return memo[k];
}
memo[k] = (p * Digui2(a0, a1, p, q, k - 1) + q * Digui2(a0, a1, p, q, k - 2))%10000; // 否则计算该值并保存到备忘录中
return memo[k];
}
int main() {
//递推公式
//an=p×a(n−1)+q×(an−2)
//先判断k是多少
//k为0或1 就可以直接输出 k是更大的 再使用递推公式
//接受用户输入
//a0、a1、p、q、k
int a0,a1,p,q,k;
scanf("%d %d %d %d %d", &a0, &a1, &p, &q, &k);
printf("%d", Digui2(a0, a1, p, q, k)%10000);
return 0;
}