0/1背包问题——java版
将糖果的数量看作背包的容量,将牛牛看作物品,牛牛需要糖果的数量看作物品的重量,牛牛的数量看作物品的价值。
至于约定,只需要将有约定的两只牛打包成一个物品,这个物品的重量为两只牛需要的糖果数量和,物品的价值为2(两只牛)。
代码如下:
public class Main{
public static void main(String[] args){
Scanner cin = new Scanner(System.in);
int n = cin.nextInt();
int m = cin.nextInt();
int[] cow = new int[n + 1];
for(int i = 1; i <= n; i++){
cow[i] = cin.nextInt();
}
int k = cin.nextInt();
Map<Integer, Integer> map = new HashMap<>();
for(int x = 0; x < k; x++){
int i = cin.nextInt();
int j = cin.nextInt();
map.put(i, j);
map.put(j, i);
}
// 下面是合并两只有约定的牛
// list中存放的数组有两个元素,一个是需要吃的糖果数量,一个是奶牛的数量
List<int[]> list = new ArrayList<>();
for(int i = 1; i <= n; i++){
if(map.containsKey(i)){
if(map.get(i) == null){
continue;
}
int j = map.get(i);
int sum = cow[i] + cow[j];
list.add(new int[]{sum, 2});
map.put(j, null);
}else{
list.add(new int[]{cow[i], 1});
}
}
// 下面是0/1背包代码,m是背包的容量
int[] dp = new int[m + 1];
for(int i = 0; i < list.size(); i++){
int w = list.get(i)[0];
int c = list.get(i)[1];
for(int j = m; j >= w; j--){
dp[j] = Math.max(dp[j], dp[j - w] + c);
}
}
System.out.println(dp[m]);
}
}