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]);
	
}
	
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值