神考四题题解+记忆化操作:

这四题用递归写法:数据量40--50可能就跑不动了

所以这里涉及一个记忆化的小技巧
因为递归是一直递归到最后的结束条件,所以有些不用递归到最后
就可以结束了,比如我们要求6的阶乘,第一次求了6的阶乘,我们再
准备求3的阶乘的时候,其实已经不用求了,因为在求6的阶乘的时候
已经把3的阶乘求过了

看一下代码理解一下:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 1005
ll dp[maxn];//做记忆化的辅助数组
ll s_mul(ll n)//阶乘
{
    if(n==0)//0的阶乘是1
        return 1;
    dp[n]=n*s_mul(n-1);
}
int main()
{
    ll n;
    n=20;
    s_mul(n);//相当于预处理
    int t;
    scanf("%d",&t);
    while(t--)
    {
        ll x;
        scanf("%lld",&x);
        printf("%lld\n",dp[x]);
    }
   puts("\n");

}

看一下结果:共20组,从1到20的阶乘结果
在这里插入图片描述

我写上面这个代码的过程,是因为对于下面有的题解可能有人不太理解的,所以对记忆化进行解释,对递归的结束条件适当的修改会减少时间的复杂度,有些就不用递归到最后一层去找答案,因为在之前的递归中已经找到了答案,我们只需要把答案存起来即可,当用到的时候拿来用即可

神考一:

#include<cstdio>
using namespace std;
#define ll long long
#define maxn 1005
ll dp[maxn];
ll pass(ll x)
{
    if(dp[x])
        return dp[x];
    if(x==1||x==2)
        return 1;
      return dp[x]=pass(x-2)+pass(x-1);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        ll n;
        scanf("%lld",&n);
        ll ans=pass(n);
        printf("%lld\n",ans);
    }
}

神考二:

#include<cstdio>
using namespace std;
#define ll long long
#define maxn 1005
ll dp[maxn];
ll pass(ll x)
{
    if(x==0)
    return 3;
    return (pass(x-1)-1)*2;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        ll n;
        scanf("%lld",&n);
        ll ans=pass(n);
        printf("%lld\n",ans);
    }
}

神考三:

#include<cstdio>
using namespace std;
#define ll long long
#define maxn 1005
ll dp[maxn][maxn];
ll pass(ll a,ll b)
{
    if(dp[a][b])
        return dp[a][b];
    if(a==b)
    return 1;
    if(b<a)
        return 0;
    return dp[a][b]=pass(a,b-1)+pass(a,b-2);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        ll a,b;
        scanf("%lld %lld",&a,&b);
        ll ans=pass(a,b);
        printf("%lld\n",ans);
    }
}

神考四:

#include<cstdio>
using namespace std;
#define ll long long
#define maxn 1005
ll dp[maxn][maxn];
ll pass(ll x)
{

    if(x==1)
        return 1;
    return (pass(x-1)+1)*2;
}
int main()
{
    ll t;
//    scanf("%d",&t);
    while(~scanf("%lld",&t))
    {
//        scanf("%lld",&t);
        ll ans=pass(t);
        printf("%lld\n",ans);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值