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

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

/**
 * 想用贪心来写个矩阵连乘试一试
 * 思路:把矩阵按公共的行列从大到小排序,然后按此顺序计算
 * @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));
	}
}

你可能感兴趣的:(算法)