TZOJ 3091 CB数列

描述

CB发现了一种奇怪的数列,命名为CB数列。这种奇怪的数列具有如下的性质:
  1)所有数都是正整数;
  2)数列中后一个数不小于前一个数的两倍;
比如,n=6
6
1 6
2 6
3 6
1 2 6
1 3 6
共有6种方案。
  CB想用CB数列考考2B铅笔。他给出一个正整数n,让2B铅笔计算,以n结尾(即最后一个元素等于n)的这种数列有多少个?
  当然,CB不想让2B铅笔轻松地解决这个问题,所以他把n的范围定得很大,n可以是两千以内的任何正整数。2B铅笔该如何解决这个问题呢?

输入

输入包含多组数据。每组数据包含一个正整数n(n<=2000)。

输出

对应每组输入,输出一个正整数,即符合要求的数列有多少个。

样例输入

4
6
7

样例输出

4
6
6

思路就是dp+递归,这一题的递归式有难度

注意到CB数列是前n/2项加上n,即末尾是n,则倒数第二项为小于\left[ \frac{n}{2} \right]

递推式为f(n)=f(1)+f(2)+......+f(\left[ \frac{n}{2}\right])+1

显然复杂度为\mathcal{O}\left ( n^{2} \right )

那我们就要找跟好的递推式,此时要用到高中数列的技巧

再写将n-1带入式子相减(注意分奇偶)得到

f(n)=f(n-1)+(1-n\bmod2)*f(\left[ \frac{n}{2} \right] )

#include <bits/stdc++.h>

long long int dp[2010];

long long int count_cb_sequences(int n)
{
    if(n==1)
        return 1;
    if(dp[n])
        return dp[n];
    dp[n]=count_cb_sequences(n-1)+(1-n%2)*count_cb_sequences(n/2);
    return dp[n];
}

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        printf("%lld\n",count_cb_sequences(n));
    }
	return 0;
}

可恶python说我递归太多(nao)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值