计数dp:
leetcode413. 等差数列划分
class Solution:
def numberOfArithmeticSlices(self, nums: List[int]) -> int:
#dp[i]表示以num[i]结尾的等差数列的个数,可以看出dp[i]可以从dp[i-1]推来,
#例如:[1,2,3]---dp[2]=1而[1,2,3,4]以4结尾的等差数列个数为dp[3]=2,
#一个是dp[2]的延续,个数即dp[2]本身,
#另外一个是[2,3,4]新加的,所以dp[i]=dp[i-1]+1
n=len(nums)
if n<3:
return 0
d=nums[1]-nums[0]
dp=[0]*n
res=0
for i in range(2,n):
if nums[i]-nums[i-1]==d:
dp[i]=dp[i-1]+1
res+=dp[i]#把所有的方案数加起来
else:
d=nums[i]-nums[i-1]
return res
Acwing 900 整数划分
思路:转换为完全背包问题,对于数字n,相当于从1到n的数字中选择,每个数字可以选择无数次的选择方案总数。
'''
未优化最初版本完全背包
'''
n=int(input())
N=1010
mod=10**9+7
dp=[[0]*N for _ in range(N)]
dp[0][0]=1#从前0个数字中取,和恰好为0的方案数为1
for i in range(1,n+1):
for j in range(n+1):
k=0
while k*i<=j:
dp[i][j]+=dp[i-1][j-k*i]
k+=1
print(dp[n][n]%mod)
'''
二维优化版本完全背包
'''
n=int(input())
N=1010
mod=10**9+7
dp=[[0]*N for _ in range(N)]
dp[0][0]=1#从前0个数字中取,和恰好为0的方案数为1
for i in range(1,n+1):
for j in range(n+1):
dp[i][j]=dp[i-1][j]
if j>=i:
dp[i][j]+=dp[i][j-i]
print(dp[n][n]%mod)
'''
一维优化版本完全背包
'''
n=int(input())
N=1010
mod=10**9+7
dp=[0]*N
dp[0]=1#从前0个数字中取,和恰好为0的方案数为1
for i in range(1,n+1):
for j in range(i,n+1):
dp[j]=dp[j]+dp[j-i]
print(dp[n]%mod)