贪心法求解矩阵连乘和01背包

博客指出贪心算法求矩阵连乘不一定能得到最优解,虽有例子可得到最优解,但也易举反例。同时提到01背包问题用贪心算法得到的结果可能很糟糕,还介绍了贪心的几种标准,此次采用单位重量价值最大先放的标准。

思路来源:https://www.xuebuyuan.com/973538.html
贪心求矩阵连乘,不一定得到最优解。在另一篇动态规划求矩阵连乘的博客里举的那个例子是可以得到最优解的。但是也很容易举反例,比如下面这个,用下面的贪心求的是16000:
在这里插入图片描述

/**
 * 想用贪心来写个矩阵连乘试一试
 * 思路:把矩阵按公共的行列从大到小排序,然后按此顺序计算
 * @author yangtze
 * @version 2019.5.29
 */
public class Matrix_Chain2 {
	public static void main(String[] args){
		int n;//矩阵个数
		ArrayList<Integer> m = new ArrayList<Integer>();
		int[] result ;
		//Matrix_Chain matrix_Chain = new Matrix_Chain();
		
		System.out.println("请输入矩阵个数:");
		Scanner scanner = new Scanner(System.in);
		n = scanner.nextInt();
		result = new int[n-1];//做n-1次乘法
		
		//存放矩阵的行列,例如第一个矩阵的行数为m0
		//它的列数和第二个矩阵的行数为m1,第二个矩阵的列数和第三个矩阵的行数为m2..
		System.out.println("请输入矩阵的行列:");
		Scanner scanner2=new Scanner(System.in); 
		String string = scanner2.nextLine();//将用户输入的一整行字符串赋给s
		String[] c = string.split(",");//用逗号将其分割成字符串数组		
		
		for (int u = 0; u < n+1; u++) {
			m.add(Integer.parseInt(c[u]));//讲字符串数组转换成int数组
		}
		
		for(int j=0;j<n-1;j++){
			int max = 0,temp = 1;
			//不包括头尾
			for(int i=1;i<n-1;i++){			
				if(m.get(i)>max){
					max = m.get(i);
					temp = i;//得到最大的那个值的下标
				}
			}
			System.out.println(temp);
			if(m.size()>3){
				result[j]=m.get(temp-1)*m.get(temp)*m.get(temp+1);
				m.remove(temp);
			}else {
				result[j]=m.get(0)* m.get(1)* m.get(2);
			}
			
		}
		
		int sum=0;
		for(int k=0; k<n-1;k++){
			sum+=result[k];
		}
		System.out.println(sum);
	}
	
}

01背包也是一样的,用贪心得到的结果可能很糟糕。贪心的标准可以是最小重量的先放、最大价值的先放、单位重量价值最大的先放。下面采用的是第三种。

/**
 * 贪心求解01背包
 * @author 
 * 
 */
public class FindMax2 {
	static float[] weight,value,rate;
	static int num;
	static HashMap<Float, Float> map;
	//输入重量和价值
	public static void input(){
		map = new HashMap<>();
		Scanner sc=new Scanner(System.in);
		System.out.println("please input the number of the things:");
		num = sc.nextInt();
		
		rate = new float[num];
		weight = new float[num];
		value = new float[num];
		
		System.out.println("请输入每个物品的重量、价值:");		
		int j=num;
		while(j>0){
			float weight = sc.nextFloat();
			float value = sc.nextFloat();			
			map.put(weight, value);			
			j--;
		}
		System.out.println(map.toString());
	}
	
	//从大到小排序
	public static void Sort(float[] arr,int limit){
		int len=arr.length;
		int wei = 0;
		for(int i=0;i<len-1;i++){
			int max=i;
			for(int j=1+i;j<len;j++){
				if(arr[j]>arr[max]){
					max=j;
				}
			}
			wei += weight[max];
			if(wei<=limit){
				System.out.println("选中第"+(max+1)+"个物品");
				if(max!=i){
					swap(arr,i,max);
				}
			}else{
				return;
			}
			
		}
	}
	
	public static void swap(float arr[],int a,int b){
		float temp=arr[a];
		arr[a]=arr[b];
		arr[b]=temp;
	}
	
	//求比例并从大到小排序
	public static void rateSort(int limit){
		
		int index=0;
		Iterator iterator = map.entrySet().iterator();
		while(iterator.hasNext()){
			Map.Entry entry = (Map.Entry)iterator.next();
			float wei = Float.parseFloat(entry.getKey().toString());
			float val = Float.parseFloat(entry.getValue().toString());
			//System.out.println(wei+","+val);
			weight[index] = wei;
			value[index] = val;
			rate[index] = val/wei;
			index++;
		}
		System.out.println("单位重量的价值:"+Arrays.toString(rate));
		Sort(rate,limit);
	}
	
	public static void main(String[] args){
		
		System.out.println("请输入背包容量:");
		Scanner scanner = new Scanner(System.in);
		int limit = scanner.nextInt();
		input();
		rateSort(limit);
		System.out.println("按单位重量的价值从大到小排序:"+Arrays.toString(rate));
	}
}

一、选择题\n1.算法必须具备输入、输出( D )等4个特性。\nA.可行性安全性 B.确定性易读性\nC.有穷性安全性 D.有穷性确定性\n\n2.算法分析中,记号O表示( B ),记号Ω表示( A )\nA.渐进下界 B.渐进上界\nC.非紧上界 D.紧渐进界\n\n3.假设某算法在输入规模为n时的计算时间为T(n)=32^n。在某台计算机上实现并完成概算法的时间为t秒。现有另一台计算机,其运行速度为第一台的64倍,那么在这台新机器上用同一算法在t秒内能解输入规模为多大的问题?( B )解题方法:32n*64=3*2x\nA.n+8 B.n+6\nC.n+7 D.n+5\n4.设问题规模为N时,某递归算法的时间复杂度记为T(N),已知T(1)=1,T(N)=2T(N/2)+N/2,用O表示的时间复杂度为( C )。\nA.O(logN) B.O(N)\nC.O(NlogN) D.O(N²logN)\n5.直接或间接调用自身的算法称为( B )。\nA.贪心算法 B.递归算法\n\nC.迭代算法 D.回溯法\n6.Fibonacci数列中,第4个第11个数分别是( B )。\nA.5,89 B.3,89\nC.5,144 D.3,144\n7.在有8个顶点的凸多边形的三角剖分中,恰有( B )。\nA.6条弦7个三角形 B.5条弦6个三角形\nC.6条弦6个三角形 D.5条弦5个三角形\n8.一个问题可用动态规划算法贪心算法求解的关键特征是问题的( B )。\nA.重叠子问题 B.最优子结构性质\nC.贪心选择性质 D.定义最优解\n9.下列哪个问题不用贪心法求解( C )。\nA.哈夫曼编码问题 B.单源最短路径问题\nC.最大团问题 D.最小生成树问题\n10.下列算法中通常以自底向上的方式求解最优解的是( B )。\nA.备忘录法 B.动态规划法\nC.贪心法 D.回溯法\n11.下列算法中不能解决0/1背包问题的是( A )。\nA.贪心法 B.动态规划\nC.回溯法 D.分支限界法\n12.下列哪个问题可以用贪心算法求解( D )。\nA.LCS问题 B.批处理作业问题\nC.0-1背包问题 D.哈夫曼编码问题\n13.用回溯法求解最优装载问题时,若待选物品为m种,则该问题的解空间树的结点个数为( )。\nA.m! B.2m+1\nC.2m+1-1 D.2m\n\n14.二分搜索算法是利用( A )实现的算法。\nA.分治策略 B.动态规划法\nC.贪心法 D.回溯法\n15.下列不是动态规划算法基本步骤的是( B )。\nA.找出最优解的性质 B.构造最优解\nC.算出最优解(应该是最优值) D.定义最优解\n16.下面问题( B )不能使用贪心法解决。\nA.单源最短路径问题 B.N皇后问题\nC.最小花费生成树问题 D.背包问题\n17.使用二分搜索算法在n个有序元素表中搜索一个特定元素,在最好情况最坏情况下搜索的时间复杂性分别为( A )。\nA.O(1),O(logn) B.O(n),O(logn)\nC.O(1),O(nlogn) D.O(n),O(nlogn)\n18.优先队列式分支限界法选取扩展结点的原则是( C )。\nA.先进先出 B.后进先出\nC.结点的优先级 D.随机\n19.下面不是分支界限法搜索方式的是( D )。P161\nA.广度优先 B.最小耗费优先\nC.最大效益优先 D.深度优先\n20.分支限界法解最大团问题时,活结点表的组织形式是( B )。\nA.最小堆 B.最大堆\nC.栈 D.数组\n21.下列关于计算机算法的描述不正确的是( C )。\nA.算法是指解决问题的一种方法或一个过程\nB.算法是若干指令的有穷序列\nC. 算法必须要有输入输出****\nD.算法是编程的思想\n22.下列关于凸多边形最优三角剖分问题描述不正确的是( A )。\nA.n+1个矩阵连乘的完全加括号n个点的凸多边形的三角剖分对应\nB.在有n个顶点的凸多边形的三角剖分中,恰有n-3条弦\nC.该问题可以用动态规划法来求解\nD.在有n个顶点的凸多边形的三角剖分中,恰有n-2个三角形\n23.动态规划法求解问题的基本步骤不包括( C )。\nA.递归地定义最优值\nB.分析最优解的性质,并刻画其结构特征\nC.根据计算最优值时得到的信息,构造最优解 (可以省去的)\nD.以自底向上的方式计算出最优值\n24.分治法所能解决的问题应具有的关键特征是( C )。\nA.该问题的规模缩小到一定的程度就可以容易地解决\nB.该问题可以分解为若干个规模较小的相同问题\nC.利用该问题分解出的子问题的解可以合并为该问题的解\nD.该问题所分解出的各个子问题是相互独立的\n\n25.下列关于回溯法的描述不正确的是( D )。\nA.回溯法也称为试探法\nB.回溯法有“通用解题法”之称\nC.回溯法是一种能避免不必要搜索的穷举式搜索法\nD.用回溯法对解空间作深度优先搜索时只能用递归方法实现\n26. 常见的两种分支限界法为( D )。\nA. 广度优先分支限界法与深度优先分支限界法;\nB. 队列式(FIFO)分支限界法与堆栈式分支限界法;\nC. 排列树法与子集树法;\nD. 队列式(FIFO)分支限界法与优先队列式分支限界法;
最新发布
01-04
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值