贪心法求解矩阵连乘和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));
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值