我的算法与设计第一课----暴力解决背包问题

我的算法与设计第一课----暴力解决背包问题

第一次在写博客,还是在CSDN上写,有点小激动。纪念一下①。

摘要

算法与设计是刚开的一门课,简单粗暴,上机的第一课,直接就是一个word,给你问题让你解决。没错,这次的主人公就是这货,背包问题
个人理解,背包问题就是一个求最优解的问题,想出好的算法优化问题进行最优解的解答,显而易见刚开课的我们,最适合最能提高代码写作能力的就是暴力求解问题了。
问题: 给定n种物品和一个书包。物品I的重量是wi,其价值为vi,背包的容量为c。问应如何选择装入背包的物品,使得装入背包中物品的总价值最大?在装入背包时,每种物品I只有两种选择:装入或者不装入。既不能装入多次,也不能只装入一部分.

表格如下:

标号1234
重量wi3452
价值vi7992

问题分析:

(1)考虑输入:因为个人因素,写程序的时候比较喜欢自己控制,所以我在这里不会因为题目而写‘特解’,我更倾向于‘通解’。那么也就是需要我们手动输入数据,根据题目给出的条件我们可以看出重量和价值之间存在一定的关系,那么我们存储数据的时候就采用二维数组存储(在这里我把第一行作为物品i的重量,把第二行作为物品i的价值进行关联,即2行n列,为了让坐标对齐,我们从下标为1开始存储,所以最终采用了2行n+1列的二维数组),而避免麻烦,我们都采用了静态数组存储数据,因为边界值的关系,我们只需要定义一个长度为n的就足够使用

(2)考虑题目大体框架:考虑暴力解决最简单的就是你只需要考虑如何解决问题,而不是如何优雅的搞定它。这个问题首先考虑的就是解答方式,这一步我们不需要写代码,只需要在思考,记录。背包问题是最优解,也就是说,我们需要在重量不超过背包容量c的基础上让价值最高----脑海中浮现需要的函数,需要判断大小(if),需要更新即需要不断找寻最大值即需要循环(for or while)

(3)考虑输出:(作为已经写完了代码的,按理说这一步并不是我原先就想到的,但因为是记录,我还是把它放到了应该有的地方。)输出的时候我们首先必须要的就是输出最优值,但这个问题显然还需要当我们知道最优解的时候,我们的最佳配置应该是什么,那么又得到了一个信息,我们需要存储最优配置,并且与最优解同时进行更新。那么我们需要数组来进行。

(4)考虑细节:这个环节,我最喜欢用的方法就是举一个特定的例子然后进行分析,在这里因为稍微有点复杂所以就举个例子吧,你假设把第 i 个物品放入(在这里注意最好是假设第一次放入,保证你过程的完整性),这时候需要考虑什么,什么值发生了改变。以及你所需要的函数如何正确使用他们。

硬货环节

package bag;
import java.io.*;
import java.util.Scanner;
public class Bag {
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		   Scanner sc = new Scanner(System.in); 
		   System.out.print("请输入背包容量:");
		   int c = sc.nextInt();
		   System.out.print("请输入物品种类数量:");
		   int n = sc.nextInt();
		   int[][] goods = new int[n+1][2];
		   for(int i=1;i<n+1;i++) {
			   System.out.print("请输入第"+i+"种物品重量:");
			   goods[i][0] = sc.nextInt(); 
			   System.out.print("请输入第"+i+"种物品价值:");
			   goods[i][1] = sc.nextInt();
		   }
		   int[] result = new int[n]; //循环内保存当前背包配置
		   int[] best_result = new int[n];
		   int final_number=0;// 最终背包内物品数量
		   int best_values = 0;//最佳总价值
		   for(int i=1;i<n;i++) {
			   int w = c - goods[i][0];
			   int v = goods[i][1];
			   int flag=0;
			   result[flag] = i;
			   for(int j=i+1;j<=n;j++) {
				   if(goods[j][0]<=w) {
					   flag++;
					   result[flag] = j;
					   v = v + goods[j][1];
					   w = w - goods[j][0];
				   }
				   else {
					   continue;
				   }
			   }
			   if(best_values<v) {
				   best_values = v;
				   final_number = flag;
				   for(int m=0;m<=flag;m++) {
					   best_result[m] = result[m];
				   }
			   }
			   else {
				   continue;
			   }
		   }
		   System.out.print("最佳重量为:"+best_values);
		   System.out.print("最佳重量的配置为:");
		   for(int i = 0;i<=final_number;i++) {
			   System.out.print(" "+best_result[i]);
		   }
	}
}

吐槽

(0)这次因为是上课写的所以只有Java版本,(暗示以后可能优先使用Java版本发表),但后面还是会写一个Python版本的暴力解决背包问题(毕竟还要练习Python)
(1)这个题目竟然开始说不能一部分放,这? 脑洞多大才能放一部分
(2)这个CSDN-markdown编译器好难用啊,在win 10中的Microsoff Edge里不能粘贴复制,而且有的功能不能拓展(或许是我没找到诀窍)表格我都是用html写的,希望能渐渐适应吧
(3)强烈推荐追求问题的通解,只思考特解以后会吃亏,也不利于我们代码水平的提高
(4)下次再见,不定期更新博客,希望大家喜欢,也不知道可不可以留言,有的话尽管提意见,我会慢慢改善的嘻嘻

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值