题目描述
小明每周上班都会拿到自己的工作清单,工作清单内包含n项工作,每项工作都有对应的
耗时时间(单位h)和报酬,工作的总报酬为所有已完成工作的报酬之和,那么请你帮小明安
排一下工作,保证小明在指定的工作时间内工作收入最大化。
输入描述
输入的第一行为两个正整数T,n
T代表工作时长(单位h,0<T<1000000),
n代表工作数量(1<n<=3000)
接下来是n行,每行包含两个整数t,w
t代表该工作消耗的时长(单位h,t>0),w代表该项工作的报酬
输出描述
输出小明指定工作时长内工作可获得的最大报酬
用例
输入
40 3
20 10
20 20
20 5
输出
30
// 01背包问题
//1、初始化二维数组int[i + 1][j + 1];i为物品的下表,j为背包的容量,因为有背包为0和物品为0的情况,所以初始化数组要+1;
//2、当第i个物品重量放不下背包时,则dp[i][j] = dp[i - 1][j],第i个物品的重量背包放不下,所以只能放i-1之前的物品,所以和dp[i-1][j]就是d[i][j]最大的。
//3、当第i个物品可以放下的时候,则有两种情况,要不要放第i个物品,如果放,那么背包就应该空出来第i个物品的重量,所以我们要找背包j - 第i个物品重量的背包能放的最大重量是多少。 dp[i][j] = dp[i-1][j - weight[i]] + weight[i];如果不放,则dp[i][j] = dp[i-1][j];
所以dp[i][j] = Math.max(dp[i-1][j - weight[i]] + weight[i], dp[i-1][j]);
public class Main{
public static void mian() {
Scanner scanner = new Scanner(System.in);
int m = scanner.nextInt(); //背包重量
int n = scanner.nextInt(); //物品个数
int[] weight = new int[n]; //物品重量
int[] value = new int[n]; //物品价值
for(int i = 0; i < n; i++) {
weight[i] = scanner.nextInt();
value[i] = scanner.nextInt();
}
int[][] dp = new int[m + 1][n + 1];
for(int i = 1; i <= n; i ++) {
for(int j = 1; j <= m; i++) {
if (value[i] > j) {
dp[i][j] = dp[i-1][j];
} else {
dp[i][j] = Math.max(dp[i-1][j-value[i]] + value[i], dp[i-1][j]);
}
}
}
return dp[m + 1][n + 1];
}
}