GDUT_排位赛题解报告_第5场_C. 积木

题目:

ChenJr已经两个月没有出门了,因此他已经无聊到开始用积木来玩搭房子游戏了。

ChenJr首先规定,对于搭建的每一栋房子,他只能选取长度为n的积木作为地基,之后他根据下述的规则进行搭建。

如果当前搭建的房子的最顶端的积木块的长度为k,那么ChenJr可以选择一个正整数i,(i∈[1,k2]),并在房子顶端放置一个长度为i的积木。或者ChenJr可以选择不再继续放置积木,代表当前的房子已经搭建好了。

ChenJr不喜欢搭建款式相同的房子,而两个房子的款式相同,当且仅当两个房子使用的种类和数量都相同。现在你可以认为ChenJr有无穷个大小在[1,n]的积木,现在你需要告诉ChenJr,ChenJr最多可以搭建多少个不同款式的房子。最后的结果可能会很大,你需要将结果mod 109+7。

Input
一行输入一个正整数n (1≤n≤106),代表ChenJr只能选取长度为n的积木作为地基。

Output
一行输出ChenJr最多可以搭建多少个不同款式的房子。你需要将你得出的答案mod 109+7。

Examples
inputCopy
1
outputCopy
1
inputCopy
4
outputCopy
4
Note
对于样例2,可以构建3种不同的房子:

房子1:4
房子2: 4 2
房子3: 4 1
房子4: 4 2 1
(数字从左到右依次为地基到顶端的积木长度)

这个题意就是给出一个n,然后让你以n为基底,每次往上面放的限制都是上一层的n/2以下,问多少种不同的放法;
然后就知道n基底,然后上面的数就是n/2…1和不放;如果是n/2,怎么在n/2上面放呢,那么问题已经呼之欲出,这就是一个dp,dp[i]表示i为基底的放法:dp[i]=dp[i/2]+…+dp[1]+1 (除了i自己上面什么都不放);

但是我们会发现一个问题,dp[i/2]+…+dp[1]太多了,总不能for把,所以我们用一个前缀和all[i]=dp[i]+…+dp[1]。

核心代码:

dp[1]=1;
	all[1]=1;
	for(int time=2;time<1000001;time++)
	{
		dp[time]=all[time/2]+1;
		dp[time]%=mod;
		all[time]=all[time-1]+dp[time];
		all[time]%=mod;
	}
	printf("%d\n",dp[n]);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值