java算法——01背包问题

背包问题我是看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]);
	
}
	
}

猜你喜欢

转载自blog.csdn.net/weixin_44919936/article/details/114239497