AcWing 900. 整数划分-python
原题链接
简单
作者:
Actor丶
,
2020-02-16 09:36:13
,
所有人可见
,
阅读 755
1.完全背包思想
"""
基本思想:
等价于完全背包问题,n个物品,第i个物品的体积和价值都为i,并且求价值恰好为n的划分方案个数
1. 状态表示:
1.1 集合f[i,j]:表示由前i个数组成的体积恰好为j的划分方案集合
1.2 属性:count,即划分方案的个数
2. 状态计算(状态转移方程,根据选择第i个数的次数是0,1...s,进行划分):
因为:
f[i][j] = f[i-1][j] + f[i-1][j-i] + f[i-1][j-2*i] + f[i-1][j-3*i] +...+ f[i-1][j-s*i]
f[i][j-i] = f[i-1][j-i] + f[i-1][j-2*i] + f[i-1][j-3*i] +...+ f[i-1][j-s*i]
所以:
f[i][j] = f[i-1][j] + f[i][j-i]
输入样例:
5
输出样例:
7
"""
# 输入示例
mod = 1e9 + 7
n = int(input().strip())
# 初始化dp数组
dp = [0 for i in range(n+1)]
dp[0] = 1 # !!!注意:当n=0时,只有一种方案,即什么都不选
# 状态计算
for i in range(1, n+1): # 等价于遍历n个物品,其中第i个物品的体积为i
for j in range(1,n+1): # 等价于遍历不同的体积 !!!出错:优化版本的完全背包问题的内层循环要从i开始,即只用当容量j大于体积i时才更新
if j>=i:
dp[j] = (dp[j]+dp[j-i])%mod
print(int(dp[-1]))
2. 多重背包思想(超时)
"""
基本思想:
等价于多重背包问题,n个物品,第i个物品的体积和价值都为i,并且求价值恰好为n的划分方案个数
1. 状态表示:
1.1 集合f[i,j]:表示由前i个数组成的体积恰好为j的划分方案集合
1.2 属性:count,即划分方案的个数
2. 状态计算(状态转移方程,根据选择第i个数的次数是0,1...s...n,进行划分):
if s*i<=n
f[i][j] = f[i-1][j] + f[i-1][j-i] + f[i-1][j-2*i] + f[i-1][j-3*i] +...+ f[i-1][j-n*i]
输入样例:
5
输出样例:
7
"""
# 输入示例
mod = 1e9 + 7
n = int(input().strip())
# 初始化dp数组
dp = [0 for i in range(n+1)]
dp[0] = 1 # !!!注意:当n=0时,只有一种方案,即什么都不选
def IntHuafen(n):
for i in range(1,n+1):
for j in range(n,i-1,-1):
tmp = 0
for s in range(n+1):
if s*i<=j:
# dp[j] += dp[j-s*i] # !!!出错:不能写成dp[j] += dp[j-s*i]的形式,否则当s*i==0时,dp[i-1][j]被算了两次,即dp[j] += dp[j]
tmp += dp[j-s*i]
dp[j] = tmp%mod
# print(dp[j])
print(int(dp[-1]))
IntHuafen(n)