背包问题我是看b站的视频学的
一开始我看打表法是看的一脸懵,直到看一个大佬用树的形式去延申开来才明白动态规划的大致意思
附一个自己画的动态规划树
含义大致就是先判断当前编号的重量是否超过能承受的最大重量,如果不能,则退到上一个编号去考虑。如果能承受,则又有两种方法,一种是退到上一个编号去分配,另一种就是把当前编号的物品拿走,这样的话也会退到上一个编号,不过此时能承受的最大重量则需要减去刚刚放进去的物品的重量,而且当前加上已经放进去物品的价值,以此规律去拓展到第一个物品或则能承受的重量为0。
关键代码:
for(int i =1;i<5;i++) //物品的编号
for(int j =1;j<9;j++) //能承受的最大重量,一个界限
{
if(w[i]>j)
f[i][j] = f[i-1][j];
else
f[i][j] = Math.max(f[i-1][j], f[i-1][j-w[i]]+v[i]);
}
完整代码:
package luogu;
public class BeiBao {
public static void main(String[] args) {
int [][]f = new int [5][9];
int w[] = new int [] {
0,2,3,4,5};
int v[] = new int [] {
0,3,4,5,8};
for(int i =1;i<5;i++) //物品的编号
for(int j =1;j<9;j++) //能承受的最大重量,一个界限
{
if(w[i]>j)
f[i][j] = f[i-1][j];
else
f[i][j] = Math.max(f[i-1][j], f[i-1][j-w[i]]+v[i]);
}
System.out.println(f[4][8]);
}
}
————————————————
P1048类似背包问题:
代码如下:
package luogu;
import java.util.Scanner;
public class P1048 {
//背包问题
static int t,m;
static int a[] = new int [100]; //采药时间
static int b[] = new int [100]; //采药价值
static int f[][] = new int [11][1000];
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
t = in.nextInt();
m = in.nextInt();
for(int i=1;i<=m;i++)
{
a[i] = in.nextInt();
b[i] = in.nextInt();
}
for(int i=1;i<=m;i++)
for(int j=1;j<=t;j++)
{
if(a[i]>j) f[i][j] = f[i-1][j];
else {
f[i][j] = Math.max(f[i-1][j], f[i-1][j-a[i]]+b[i]);
}
}
System.out.println(f[m][t]);
}
}