背包问题
问题分析
计算物品的单位价值,然后尽可能多的将单位重量价值高的物品放入背包中。
代码
import java.util.Arrays;
import java.util.Scanner;
public class one {
static Scanner scanner = new Scanner(System.in);
static class item implements Comparable<item> {
private double value = 0;
private double weight = 0;
public double getPrice() {
return value/weight;
}
public item(int value, int weight) {
this.value = value;
this.weight = weight;
}
public int compareTo(item other) {
if (value / weight < other.getValue() / other.getWeight())
return 1;
if (value / weight > other.getValue() / other.getWeight())
return -1;
return 0;
}
public double getValue() {
return value;
}
public double getWeight() {
return weight;
}
public void setValue(double value) {
this.value = value;
}
public void setWeight(double weight) {
this.weight = weight;
}
}
public static void main(String args[]) {
int n, m;
n = scanner.nextInt();
m = scanner.nextInt();
item[] items = new item[n];
int[] w = new int[n];
int[] v = new int[n ];
for (int i = 0; i < n; i++) {
w[i] = scanner.nextInt();
}
for (int i = 0; i < n; i++) {
v[i] = scanner.nextInt();
items[i] = new item(v[i], w[i]);
}
Arrays.sort(items);
int i=0;
int answer = 0;
while(m!=0&&i<items.length){
if(items[i].getWeight()<=m){ //当前物体能全部装下
m-=items[i].getWeight();
answer+=items[i].getValue();
items[i].setWeight(0);
i++;
}else{
answer+=m*items[i].getPrice();
items[i].setWeight(items[i].getWeight()-m);
m=0;
}
}
System.out.println("背包中物品的最大价值为: "+answer);
System.out.println("依次装入背包的物品为:");
for(int j=0;j<items.length;j++){
System.out.println("第"+j+"个物品:"+(w[j]-items[j].getWeight())/w[j]);
}
}
}
测试输入
3 50
10 20 30
60 100 120
测试输出
背包中物品的最大价值为: 240
依次装入背包的物品为:
第0个物品:1.0
第1个物品:1.0
第2个物品:0.6666666666666666
运行结果
最优装载
问题分析
先按照重量排序,之后就从小到大选择箱子就行,直到船放不为止。
代码
import java.util.Arrays;
import java.util.Scanner;
public class two {
static Scanner scanner = new Scanner(System.in);
static class item implements Comparable<item> {
private int index;
private double weight = 0;
public item(int index, double weight) {
this.index = index;
this.weight = weight;
}
public int compareTo(item other) {
if (weight > other.getWeight())
return 1;
if (weight < other.getWeight())
return -1;
return 0;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public int getIndex() {
return index;
}
@Override
public String toString() {
return "item{" +
"index=" + index +
", weight=" + weight +
'}';
}
}
public static void main(String args[]) {
int n, m;
n = scanner.nextInt();
m = scanner.nextInt();
item[] items = new item[n];
int[] w = new int[n];
for (int i = 0; i < n; i++) {
w[i] = scanner.nextInt();
items[i] = new item(i, w[i]);
}
Arrays.sort(items);
int i = 0;
int answer = 0;
while (m != 0 && i < items.length) {
if (items[i].getWeight() <= m) { //当前物体能全部装下
m -= items[i].getWeight();
answer += items[i].getWeight();
items[i].setWeight(0);
i++;
}else{
break;
}
}
System.out.println("最优装载重量为: " + answer);
System.out.println("最优装载下被选中的集装箱序号为: ");
int []indexs=new int [n];
int k=0;
for (int j = 0; j < items.length; j++) {
if(items[j].getWeight()==0)
indexs[k++]=items[j].getIndex();
}
Arrays.sort(indexs);
for (int j = n-k; j <= k; j++) {
System.out.print(indexs[j]+" ");
}
}
}
测试输入
4 5
2 3 1 1
测试输出
最优装载重量为: 4
最优装载下被选中的集装箱序号为:
0 2 3
运行结果
实验总结
贪心算法的特性(满足后可使用):
1:贪心选择
指原问题的整体最优解可以通过一系列的局部最优解得出,应用同一规则,将原问题转化为一个相似但规模更小的子问题,而后每一步都是当前最佳的选择。这种选择依赖于已做出的选择。同时,贪心策略无回溯过程。
2:最优子结构
当一个问题的最优解包含其子问题的最优解时,称此问题为最优子结构性质。这个性质是该问题能否用贪心解决的关键。
贪心算法的使用步骤:
1:制定贪心策略选择一个当前看上去最好的方案(方案的选择尤为重要)。
2:根据贪心策略一步一步获得局部最优解。
3:将所有的局部最优解和成为原来问题的一个最优解。