- 知道秘密的人数-递归法
在第 1 天,有一个人发现了一个秘密。
给你一个整数 delay ,表示每个人会在发现秘密后的 delay 天之后,每天 给一个新的人 分享 秘密。同时给你一个整数 forget ,表示每个人在发现秘密 forget 天之后会 忘记 这个秘密。一个人 不能 在忘记秘密那一天及之后的日子里分享秘密。
给你一个整数 n ,请你返回在第 n 天结束时,知道秘密的人数。由于答案可能会很大,请你将结果对 109 + 7 取余 后返回。
示例 1:
输入:n = 6, delay = 2, forget = 4
输出:5
解释:
第 1 天:假设第一个人叫 A 。(一个人知道秘密)
第 2 天:A 是唯一一个知道秘密的人。(一个人知道秘密)
第 3 天:A 把秘密分享给 B 。(两个人知道秘密)
第 4 天:A 把秘密分享给一个新的人 C 。(三个人知道秘密)
第 5 天:A 忘记了秘密,B 把秘密分享给一个新的人 D 。(三个人知道秘密)
第 6 天:B 把秘密分享给 E,C 把秘密分享给 F 。(五个人知道秘密)
示例 2:
输入:n = 4, delay = 1, forget = 3
输出:6
解释:
第 1 天:第一个知道秘密的人为 A 。(一个人知道秘密)
第 2 天:A 把秘密分享给 B 。(两个人知道秘密)
第 3 天:A 和 B 把秘密分享给 2 个新的人 C 和 D 。(四个人知道秘密)
第 4 天:A 忘记了秘密,B、C、D 分别分享给 3 个新的人。(六个人知道秘密)
这一题,挺有意思的,我的代码如下:
int konw_people_num(int n,int know_day,int forget,int delay,int today){
if(today<n){
if(know_day<=forget&&know_day>delay){
return konw_people_num(n,know_day+1,forget,delay,today+1)+konw_people_num(n,2,forget,delay,today+1);//这里注意从第二天开始,很关键,也是这个代码的一个细节问题
}
else{
return konw_people_num(n,know_day+1,forget,delay,today+1);
}
}
else{
// printf("%d ",know_day);
if(know_day>forget){
return 0;
}
else{
if(know_day>delay){
return 2;
}
else{
return 1;
}
}
}
}
int peopleAwareOfSecret(int n, int delay, int forget){
// for(int i=1;i<8;i++){
return konw_people_num(n,1,forget,delay,1);
}
上面这个代码虽然易懂,但是时间开销通过不了,所以我又优化了一下,解题代码如下,有点动态规划的感觉,但本质还是递归:
int konw_people_num2(int n,int know_day,int forget,int delay,int today,int *r,int *scell){
if(today<n){
if(know_day<=forget&&know_day>delay){
if(r[n-today]==1){
return konw_people_num2(n,know_day+1,forget,delay,today+1,r,scell)%1000000007+scell[n-today+1]%1000000007;
}
else{
return konw_people_num2(n,know_day+1,forget,delay,today+1,r,scell)+konw_people_num2(n,2,forget,delay,today+1,r,scell);
}
}
else{
return konw_people_num2(n,know_day+1,forget,delay,today+1,r,scell);
}
}
else{
// printf("%d ",know_day);
if(know_day>forget){
return 0;
}
else{
if(know_day>delay){
return 2;
}
else{
return 1;
}
}
}
}
int peopleAwareOfSecret(int n, int delay, int forget){
// for(int i=1;i<8;i++){
// printf("%d ",konw_people_num(i,1,forget,delay,1));
// }
// printf("%d ",konw_people_num(5,1,forget,delay,1));
// printf("||");
int *r=(int *)malloc(sizeof(int )*n);
int *scell=(int *)malloc(sizeof(int )*n);
for(int i=0;i<n;i++){
r[i]=0;
}
for(int i=1;i<n;i++){
scell[i]=konw_people_num2(i,1,forget,delay,1,r,scell)%1000000007;
r[i]=1;
}
return konw_people_num2(n,1,forget,delay,1,r,scell)%1000000007;
}