每日一题----P1060 [NOIP2006 普及组] 开心的金明
NOIP2006 普及组] 开心的金明 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
这个题是一个标准的01背包问题
首先确定读入元素的存储格式,可以新建一个类或者是定义两个一维数组,我这里使用的是二维数组存储,不论什么形式,只要心里明确对应位置是什么东西就可以了
然后是确定递归的必要元素(这个是从代码随想录里学到的,因此步骤与它一致,少了第五步的举例递推)
- 首先需要明确背包的每个元素的意义为:当总价值不超过 i i i时,价格与重要度乘积的最大值
- 确定递推公式: d p [ j ] = M a t h . m a x ( d p [ j ] , d p [ j − i t e m s [ i ] [ 0 ] ] + i t e m s [ i ] [ 0 ] ∗ i t e m s [ i ] [ 1 ] ) dp[j] = Math.max(dp[j], dp[j-items[i][0]] + items[i][0] * items[i][1]) dp[j]=Math.max(dp[j],dp[j−items[i][0]]+items[i][0]∗items[i][1])
- 数组初始化:刚开始时候没有装物品,因此可以全部初始化为0
- 确定遍历顺序:由于使用的一位向量表示dp变化,因此里层需要从后往前遍历
package cn.edu.xjtu.daily.April.day_4_30;
import java.util.Scanner;
/**
* @author Hydrion-QLz
* @date 2022-04-30 18:34
* @description
*/
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int[][] items = new int[m][2]; // 第一个元素为价格,第二个元素为重要度
for (int i = 0; i < m; i++) {
items[i][0] = sc.nextInt();
items[i][1] = sc.nextInt();
}
sc.close();
int[] dp = new int[n + 1];
for (int i = 0; i < items.length; i++) {
for (int j = dp.length - 1; j >= items[i][0]; j--) {
dp[j] = Math.max(dp[j], dp[j - items[i][0]] + items[i][0] * items[i][1]);
}
}
System.out.println(dp[n]);
}
}