dp数组含义:
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]=从前
i
i
i种物品中取出
j
j
j个的组合数。取不出令为0.
初始条件:
d
p
[
0
−
n
]
[
0
]
=
1
dp[0-n][0]=1
dp[0−n][0]=1
d
p
[
1
]
[
1
−
m
]
=
{
1
a
[
1
]
≥
j
0
a
[
1
]
<
j
dp[1][1-m]=\begin{cases} 1 & a[1]≥j \\ 0 & a[1]<j \end{cases}
dp[1][1−m]={10a[1]≥ja[1]<j
递推公式:
d
p
[
i
]
[
j
]
=
∑
k
=
0
m
i
n
(
j
,
a
[
i
]
)
d
p
[
i
−
1
]
[
j
−
k
]
dp[i][j]=∑_{k=0}^{min(j,a[i])}dp[i-1][j-k]
dp[i][j]=k=0∑min(j,a[i])dp[i−1][j−k]
递推方向:从上向下
时间复杂度 :
O
(
n
m
2
)
O(nm^2)
O(nm2)
优化 :
根据一般的经验,在只使用从上到下的递推的动态规划中如果能引入左到右的辅助递推,时间复杂度为更低。根据这一思想,我们化解上面的递推公式:
∑
k
=
0
m
i
n
(
j
,
a
[
i
]
)
d
p
[
i
−
1
]
[
j
−
k
]
=
∑
k
=
1
m
i
n
(
j
,
a
[
i
]
)
d
p
[
i
−
1
]
[
j
−
k
]
+
d
p
[
i
−
1
]
[
j
]
∑_{k=0}^{min(j,a[i])}dp[i-1][j-k]=∑_{k=1}^{min(j,a[i])}dp[i-1][j-k]+dp[i-1][j]
k=0∑min(j,a[i])dp[i−1][j−k]=k=1∑min(j,a[i])dp[i−1][j−k]+dp[i−1][j]
=
∑
k
=
0
m
i
n
(
j
−
1
,
a
[
i
]
−
1
)
d
p
[
i
−
1
]
[
j
−
(
1
+
k
)
]
+
d
p
[
i
−
1
]
[
j
]
=∑_{k=0}^{min(j-1,a[i]-1)}dp[i-1][j-(1+k)]+dp[i-1][j]
=k=0∑min(j−1,a[i]−1)dp[i−1][j−(1+k)]+dp[i−1][j]由于
d
p
[
i
]
[
j
−
1
]
=
∑
k
=
0
m
i
n
(
j
−
1
,
a
[
i
]
)
d
p
[
i
−
1
]
[
j
−
1
−
k
]
=
∑
k
=
0
m
i
n
(
j
−
1
,
a
[
i
]
)
d
p
[
i
−
1
]
[
j
−
(
1
−
k
)
]
dp[i][j-1]=∑_{k=0}^{min(j-1,a[i])}dp[i-1][j-1-k]=∑_{k=0}^{min(j-1,a[i])}dp[i-1][j-(1-k)]
dp[i][j−1]=k=0∑min(j−1,a[i])dp[i−1][j−1−k]=k=0∑min(j−1,a[i])dp[i−1][j−(1−k)]当
j
≤
a
[
i
]
j≤a[i]
j≤a[i]时则有
j
−
1
≤
a
[
i
]
−
1
j-1≤a[i]-1
j−1≤a[i]−1和
j
−
1
≤
a
[
i
]
j-1≤a[i]
j−1≤a[i],所以
m
i
n
(
j
−
1
,
a
[
i
]
−
1
)
=
m
i
n
(
j
−
1
,
a
[
i
]
)
=
j
−
1
min(j-1,a[i]-1)=min(j-1,a[i])=j-1
min(j−1,a[i]−1)=min(j−1,a[i])=j−1 :
∑
k
=
0
m
i
n
(
j
−
1
,
a
[
i
]
−
1
)
d
p
[
i
−
1
]
[
j
−
(
1
+
k
)
]
=
∑
k
=
0
m
i
n
(
j
−
1
,
a
[
i
]
)
d
p
[
i
−
1
]
[
j
−
(
1
+
k
)
]
=
d
p
[
i
]
[
j
−
1
]
∑_{k=0}^{min(j-1,a[i]-1)}dp[i-1][j-(1+k)]=∑_{k=0}^{min(j-1,a[i])}dp[i-1][j-(1+k)]=dp[i][j-1]
k=0∑min(j−1,a[i]−1)dp[i−1][j−(1+k)]=k=0∑min(j−1,a[i])dp[i−1][j−(1+k)]=dp[i][j−1]当
j
>
a
[
i
]
j>a[i]
j>a[i],所以
j
−
1
>
a
[
i
]
−
1
j-1>a[i]-1
j−1>a[i]−1和
j
−
1
≥
a
[
i
]
j-1≥a[i]
j−1≥a[i],故
m
i
n
(
j
−
1
,
a
[
i
]
−
1
)
=
a
[
i
]
−
1
,
m
i
n
(
j
−
1
,
a
[
i
]
)
=
a
[
i
]
min(j-1,a[i]-1)=a[i]-1,min(j-1,a[i])=a[i]
min(j−1,a[i]−1)=a[i]−1,min(j−1,a[i])=a[i]则:
∑
k
=
0
m
i
n
(
j
−
1
,
a
[
i
]
−
1
)
d
p
[
i
−
1
]
[
j
−
(
1
+
k
)
]
=
∑
k
=
0
m
i
n
(
j
−
1
,
a
[
i
]
)
d
p
[
i
−
1
]
[
j
−
(
1
+
k
)
]
−
d
p
[
i
−
1
]
[
j
−
1
−
a
[
i
]
)
]
∑_{k=0}^{min(j-1,a[i]-1)}dp[i-1][j-(1+k)]=∑_{k=0}^{min(j-1,a[i])}dp[i-1][j-(1+k)]-dp[i-1][j-1-a[i])]
k=0∑min(j−1,a[i]−1)dp[i−1][j−(1+k)]=k=0∑min(j−1,a[i])dp[i−1][j−(1+k)]−dp[i−1][j−1−a[i])]
=
d
p
[
i
]
[
j
−
1
]
−
d
p
[
i
−
1
]
[
j
−
1
−
a
[
i
]
)
]
=dp[i][j-1]-dp[i-1][j-1-a[i])]
=dp[i][j−1]−dp[i−1][j−1−a[i])]