试题 算法提高 翔集合

资源限制
时间限制:1.0s 内存限制:8.0MB
问题描述
  集合M至少有两个元素(实数),且M中任意两个元素差的绝对值都大于2,则称M为“翔集合”,已知集合S={1,2…,n},请求出n的子集中共有多少个翔集合。
输入格式
  输入共一行,一个整数n.(n>=2)
输出格式
  输出共一行,一个整数表示S的子集中共有多少个翔集合,由于个数可能过大,请输出这个值除以1000007的余数。
样例输入
4
样例输出
1
数据规模和约定
  对于20%的数据,2<=n<=1000000
  对于100%的数据,2<=n<=10^15

**思路利用动态规划来写,我写的不知道算不算动态规划,就是内存超限了。**用递归写的话真的不行,重复计算太多了。
已知f(n-1)为不包含n的所有翔集合的个数、那么我们现在只需要求出包含n的翔集合的个数两个相加就能得到f(n)和f(n-1)的关系式

  • 不包含n的情况:f(n-1)
  • 包含n的情况:要和n组成翔集合首先排除n-1和n-2这两个数,[1,n-3]只能从这里里面选取若干个组成翔集合注意到f(n-3)为Sn-3的翔集合个数它的每一个翔集合都没有n-1和n-2两个数也就式说把n加到这写集合中它们任然是翔集合,所以包含n的且个数超过2个的翔集合的个数就是f(n-3)现在只剩下2个元素的集合易得为n-3个
  • 可以得:
  • f(n)=f(n-1)+f(n-3)+n-3 (f(3)=f(2)=0,f(4)=1)
n = int(input())
mod = 1000007
s = 0
'''
内存超限
'''
nums = [0 for i in range(n)] # 记录走过的数
nums[3] = 1
# f(n) = f(n-1) + f(n-3) + n-3
for i in range(4,n):
    nums[i] = nums[i-1] + nums[i-3] + i-3+1
s = nums[-1]
print(s % mod)

递归的代码:

n = int(input())
mod = 1000007
def fun(n):
    if n <= 3:
        return 0
    elif n == 4:
        return 1 
    else:
        return fun(n-1) + fun(n-3) + n-3
s = fun(n)
print(s % mod)

这个问题暂时没有解决,有待更新,拿来记录一下想法。

参考大佬的文章:传送门

猜你喜欢

转载自blog.csdn.net/Python_Matlab/article/details/107584040
今日推荐