CCFCSP202104-4(60分) Python

首先,设dp[i]为到第i个障碍物的方案总数,而inzi(i,j,data)中的ans表示的是第i个障碍物到第j个障碍物的方案总数。(注意,是从1开始)
根据题目的分析可知,此时的ans必须为a[j]-a[i]的因子,但总体的方案数一定小于因子数(下方会介绍为何ans-1):
比如题中所给的例2:
11
0 10 20 30 40 50 60 70 80 90 100
其中,假如为第一个和第二个,之差为10,10的因子为1,10,2,5。但显然,10不能作为方案数,所以方案数小于因子数。在i和j差1的情况下如此,那么差2差3的情况下,由于还需避开中间的障碍物,所以方案数更应该小于因子数。
此外,inzi函数中最后返回的f[i][j]表示的是在i到j的整体中,没有包含在前一个中的方案数+本身因子构成的一个不可行方案。如上例子中,第一个和第二个的差为10,方案可以为1,2,5,但会包含一个10.当i和j分别为1和3时,此时差值为20,因子为1,20,2,10,4,5。此时的方案应该是4和一个不可能的方案20.
加一个不可能方案的原因是:由于f[i][j]每次的填写都是根据前一个的值,但假如ij为1和2且不包含10,那么在比较ij为1,3时候就会将10算作一个可行的方案,而10的位置为障碍物很显然没有做到屏蔽到中间的障碍物。因而最后的ans应该减去一个不可行的方案,但是f[i][j]应该包含在其中。
那么dp的动态规划的方程应该为:
在这里插入图片描述

n=int(input())
a=list(map(int,input().split()))
a.insert(0,-1)
dp=[0]*(n+1)#由于从1开始,所以要设置为n+1个
dp[1]=1
data=set()
f=[[0]*(n+1) for i in range(n+1)]
an=[[0]*(n+1) for i in range(n+1)]
def inzi(i,j,data):
    x=a[j]-a[i]
    ans=0
    if j-i==1:
        data=set()
    else:
        data=f[i+1][j].copy()
    for i in range(1,int(x**0.5)+1):
        if x%i==0:
            if i not in data:
                data.add(i)
                ans+=1
            if x//i not in data:
                data.add(x//i)
                ans+=1
    ans-=1
    return data,ans
for r in range(1,n):
    for i in range(1,n-r+1):
        j=i+r
        f[i][j]=inzi(i,j,data)[0]
        an[i][j]=inzi(i,j,data)[1]
for i in range(1,n+1):
    for j in range(i-1,0,-1):
        dp[i]+=(dp[j]*an[j][i]%1000000007)%1000000007
print(dp[n]%1000000007)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值