- 01背包
状态转移方程: d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ j ] , d p [ i − 1 ] [ j − w [ i ] ] + v [ i ] ) ∣ ∣ d p [ i − 1 ] [ j ] dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i])||dp[i-1][j] dp[i][j]=max(dp[i−1][j],dp[i−1][j−w[i]]+v[i])∣∣dp[i−1][j]
for (int i = 1; i <= n; i++)
{
for (int j = 0; j <= m; j++) {
if (j < w[i])
dp[i][j]=dp[i-1][j];
else if (j >= w[i])
dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
}
}
2.完全背包
状态转移方程:
d
p
[
i
]
[
j
]
=
m
a
x
(
d
p
[
i
−
1
]
[
j
]
,
d
p
[
i
]
[
j
−
w
[
i
]
]
+
v
[
i
]
)
∣
∣
d
p
[
i
−
1
]
[
j
]
dp[i][j]=max(dp[i-1][j],dp[i][j-w[i]]+v[i])||dp[i-1][j]
dp[i][j]=max(dp[i−1][j],dp[i][j−w[i]]+v[i])∣∣dp[i−1][j]
for (int i = 1; i <= n; i++)
{
for (int j = 0; j <= m; j++) {
if (j < w[i])
dp[i][j]=dp[i-1][j];
else if (j >= w[i])
dp[i][j]=Math.max(dp[i-1][j],dp[i][j-w[i]]+v[i]);
}
}
优化
for (int i = 0; i < n; i++)
{
int w=scanner.nextInt();
int v=scanner.nextInt();
for (int j = w; j <=m ; j++)
dp[j]=Math.max(dp[j],dp[j-w]+v);
}
3.计数
一种物品价格用其他物品价格来表示,
d
p
[
i
]
表
示
方
案
说
,
若
d
p
[
a
[
i
]
]
=
1
,
则
说
明
第
i
个
物
品
无
法
用
其
他
物
品
的
价
格
来
表
示
dp[i]表示方案说,若dp[a[i]]=1,则说明第i个物品无法用其他物品的价格来表示
dp[i]表示方案说,若dp[a[i]]=1,则说明第i个物品无法用其他物品的价格来表示
转
移
方
程
:
d
p
[
j
]
=
d
p
[
j
]
+
d
p
[
j
−
a
[
i
]
]
转移方程:dp[j]=dp[j]+dp[j-a[i]]
转移方程:dp[j]=dp[j]+dp[j−a[i]]
dp[0]=1;//dp[i]表示方案数
for (int i = 1; i <= n ; i++) {
for (int j = a[i]; j <= a[n]; j++)
{
dp[j]+=dp[j-a[i]];
}
4.数字组合
转移方程:
d
p
[
i
]
[
j
]
=
d
p
[
i
−
1
]
[
j
]
∣
∣
d
p
[
i
−
1
]
[
j
−
a
[
i
]
]
+
d
p
[
i
−
1
]
[
j
]
dp[i][j]=dp[i-1][j]||dp[i-1][j-a[i]]+dp[i-1][j]
dp[i][j]=dp[i−1][j]∣∣dp[i−1][j−a[i]]+dp[i−1][j]
import java.util.Scanner;
public class Main{
static int n,m,ans=0,x=0;
static int []a;
static int []res;
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
n=scanner.nextInt();
m=scanner.nextInt();
a=new int [1002];
for (int i = 1; i <= n ; i++) {
a[i]=scanner.nextInt();
}
int [][]dp=new int [1002][1002];
for (int i = 0; i <= n ; i++) {
dp[i][0]=1;
}
for (int i = 1; i <=n ; i++) {
for (int j = 1; j <= m ; j++) {
if (j >= a[i])
dp[i][j]=dp[i-1][j]+dp[i-1][j-a[i]];
else
dp[i][j]=dp[i-1][j];
}
}
System.out.println(dp[n][m]);
}
}
5.背包计数问题
d
p
[
j
]
=
d
p
[
j
]
+
d
p
[
j
−
a
[
i
]
]
,
d
p
[
0
]
=
1
,
只
需
将
背
包
问
题
的
m
a
x
,
改
为
s
u
m
即
可
dp[j]=dp[j]+dp[j-a[i]],dp[0]=1,只需将背包问题的max,改为sum即可
dp[j]=dp[j]+dp[j−a[i]],dp[0]=1,只需将背包问题的max,改为sum即可
Scanner scanner=new Scanner(System.in);
int n=scanner.nextInt();
int []dp=new int [1005];
int []v={10,20,50,100};
dp[0]=1;
for (int i = 0; i < 4 ; i++) {
for (int j = v[i]; j <=n ; j++) {
dp[j]+=dp[j-v[i]];
}
}
System.out.println(dp[n]);
6.无价值的01背包
d
p
[
j
]
=
m
a
x
(
d
p
[
j
]
,
d
p
[
j
−
a
[
i
]
]
+
a
[
i
]
dp[j]=max(dp[j],dp[j-a[i]]+a[i]
dp[j]=max(dp[j],dp[j−a[i]]+a[i]
for (int i = 0; i < m; i++)
{
int w=scanner.nextInt();
for (int j = H; j >=w ; j--)
{
dp[j]=Math.max(dp[j],dp[j-w]+w);
}
}