算法第二周 C : 数的计算

文章讨论了一个基于特定规则构造序列的问题,规则是每次在序列首元素左侧插入不超过其一半的正整数。通过递归和动态规划的方法,可以计算出给定初始值n时能构造的不同序列数量。例如,当n=6时,可以得到6种不同的序列。解决方案涉及建立状态转移方程dp[n]=1+dp[1]+dp[2]+...+dp[n/2]来求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

给定一个初始序列,序列中仅包含一个元素 n(1≤n≤1000)。重复以下步骤:

  1. 不做任何处理;
  2. 在序列的最左边插入一个正整数,但是这个正整数不能超过序列当前首元素的一半;

请问通过这样的规则,可以构造出多少个不同的序列。

Input

1 个正整数 n ( n ≤ 1000 )

Output

1 个整数,表示能够生成的序列个数。

Sample Input

6

Sample Output

6

Hint

当n=6,满足条件的序列为

{6},

{1, 6},

{2, 6},

{1, 2, 6},

{3, 6},

{1, 3, 6}

方法:递归

举一个例子: 

当n=6,满足条件的序列为{6},{1, 6},{2, 6},{1, 2, 6},{3, 6},{1, 3, 6}

在6的左边,第一次添加的数字可以是1、2、3      (即1->n/2)

将第一次添加的数字i以及后续的数字视为一组:dp[i]

如dp[1]包括:{1,6}

dp[2] 包括:{2,6}、{1,2,6}

dp[3]包括:{3,6}、{1,3,6}

则dp[6]=dp[1]+dp[2]+dp[3]+1,进而得到状态转移方程

dp[n]=1+dp[1]+dp[2]+dp[3]...+dp[n/2]

#include<iostream>
using namespace std;
int main()
{
    //ans=1+dp[1]+dp[2]+dp[3]+...dp[n/2]
    int dp[10000];
    int n;
    cin >> n;
    int ans = 1;
    for (int i = 1; i <= n / 2; i++)
    {
        dp[i] = 1;
        for (int j = 1; j <= i / 2; j++)
        {
            dp[i] += dp[j];
        }
        ans += dp[i];
    }
    cout << ans;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值