资产总量,资产种类,每类资产条数,每类资产价值(逗号分隔);其中每类资产条数与每类资产价值为空格分隔。
总格式如下:
资产总量,资产种类,资产A条数 资产B条数 资产C条数,资产A价值 资产B价值 资产C价值!
举例,资产总量为12,资产种类3种,3种资产条数分别为4,5,7,三种资产价值分别是500元,600元,800元,输入如下:
12,3,4 5 7,500 600 800
资产总量和资产种类都不超过1000,资产条数不超过1000,资产价值不超过10000,所有数值均为正整数。
资产包中资产最大总价值
12,3,4 5 7,500 600 800
1400
0,1背包为题动态规划的详细解析原博客地址(https://blog.csdn.net/mu399/article/details/7722810)
有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?
首先要明确这张表是至底向上,从左到右生成的。
为了叙述方便,用e2单元格表示e行2列的单元格,这个单元格的意义是用来表示只有物品e时,有个承重为2的背包,那么这个背包的最大价值是0,因为e物品的重量是4,背包装不了。
对于d2单元格,表示只有物品e,d时,承重为2的背包,所能装入的最大价值,仍然是0,因为物品e,d都不是这个背包能装的。
同理,c2=0,b2=3,a2=6。
对于承重为8的背包,a8=15,是怎么得出的呢?
根据01背包的状态转换方程,需要考察两个值,
一个是f[i-1,j],对于这个例子来说就是b8的值9,另一个是f[i-1,j-Wi]+Pi;
在这里,
f[i-1,j]表示我有一个承重为8的背包,当只有物品b,c,d,e四件可选时,这个背包能装入的最大价值
f[i-1,j-Wi]表示我有一个承重为6的背包(等于当前背包承重减去物品a的重量),当只有物品b,c,d,e四件可选时,这个背包能装入的最大价值
f[i-1,j-Wi]就是指单元格b6,值为9,Pi指的是a物品的价值,即6
由于f[i-1,j-Wi]+Pi = 9 + 6 = 15 大于f[i-1,j] = 9,所以物品a应该放入承重为8的背包
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
String[] strs = bf.readLine().split(",");
int m = Integer.parseInt(strs[0]);//可容纳的资产 条
int n = Integer.parseInt(strs[1]);//资产种类
String[] sp1 = strs[2].split(" ");
String[] sp2 = strs[3].split(" ");
int[] kinds = new int[n];
int[] prices = new int[n];
for (int i = 0; i < sp1.length; i++) {
kinds[i] = Integer.parseInt(sp1[i]);
prices[i] = Integer.parseInt(sp2[i]);
}
//动态规划
int[][] dp = new int[n + 1][m + 1];//dp[i][j],资产种类为i,背包重量为j
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
//放入第i个种类的物品,该背包的剩余重量比i类物品的重量大或者相等
//dp[i - 1][j] 为背包重量为j,不放入第i个物品的最大价值,
// 和放入第i个物品时候的价值+前面i-1类中背包容量为j-
/**
* dp[i - 1][j] 为背包重量为j,不放入第i个物品的最大价值
* dp[i - 1][j - kinds[i - 1]] + prices[i - 1] 为放入第i个物品+前i-1个物品中背包容量为j-i物品的重量的最大值
*/
if (j - kinds[i - 1] >= 0) {
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - kinds[i - 1]] + prices[i - 1]);
}else {//该类物品的重量大于背包的剩余重量了,装不下
dp[i][j] = dp[i-1][j];
}
}
}
System.out.println(dp[n][m]);
}
}
/*
0-1背包问题,考虑动态规划,
设dp[n][m]为用前n件物品占用m空间,可以获得的最大价值。
其最大价值等于1、2最大值:1、不选最后一件物品所获价值,2、选择最后一件物品所获价值
dp[n][m] = max(dp[n-1][j],dp[n-1][j-t]+v) ,t为n物品占用空间,v为n物品价值。
*/
#include<bits/stdc++.h>
using namespace std;
int main()
{
// freopen("input.txt", "r", stdin);
int m, n, i, j;
char c;
cin >> m >> c >> n >> c;
int t[n + 1], v[n + 1];
for(i = 1; i <= n; i++) cin >> t[i];
cin >> c;
for(i = 1; i <= n; i++) cin >> v[i];
int dp[n + 1][m + 1];
memset(dp, 0, sizeof(dp));
for(i = 1; i <= n; i++) {
for(j = 1; j <= m; j++) {
dp[i][j] = dp[i - 1][j];
if(t[i] <= j) {
dp[i][j] = max(dp[i][j], dp[i - 1][j - t[i]] + v[i]);
}
}
}
cout << dp[n][m] << endl;
return 0;
}
#include<bits/stdc++.h>
using namespace std;
int main()
{
int m,n;
cin>>m;getchar();cin>>n;getchar();
int zl[n+1],vl[n+1];
for(int i=1;i<=n;i++) cin>>zl[i];
getchar();
for(int i=1;i<=n;i++) cin>>vl[i];
int f[n+1][m+1];
memset(f, 0, sizeof(f));
for(int i=1;i<=n;i++)
{
for(int j=1;j<zl[i];j++)
{
f[i][j]=f[i-1][j];
}
for(int j=zl[i];j<=m;j++)
{
f[i][j]=max(f[i-1][j],f[i-1][j-zl[i]]+vl[i]);
}
}
cout<<f[n][m]<<endl;
}
谁笔试真的碰到这种真题,那就太幸福了,最基础的01背包连变形都没有。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] params = br.readLine().split(",");
int capacity = Integer.parseInt(params[0]);
int types = Integer.parseInt(params[1]);
String[] strs = params[2].split(" ");
int[] limits = new int[types];
for(int i = 0; i < types; i++){
limits[i] = Integer.parseInt(strs[i]);
}
strs = params[3].split(" ");
int[] values = new int[types];
for(int i = 0; i < types; i++){
values[i] = Integer.parseInt(strs[i]);
}
int[][] dp = new int[types][capacity + 1];
System.out.println(dfs(0, limits, values, capacity, dp));
}
private static int dfs(int index, int[] limits, int[] values, int rest, int[][] dp) {
if(index == values.length || rest <= 0){
return 0; // 到头了或当前资产拿不了了
}
if(dp[index][rest] > 0){
return dp[index][rest];
}
// 不选当前的资产
int p1 = dfs(index + 1, limits, values, rest, dp);
// 选当前的资产
int p2 = 0;
if(rest >= limits[index])
p2 = values[index] + dfs(index + 1, limits, values, rest - limits[index], dp);
dp[index][rest] = Math.max(p1, p2);
return dp[index][rest];
}
} import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] params = br.readLine().split(",");
int capacity = Integer.parseInt(params[0]);
int types = Integer.parseInt(params[1]);
String[] strs = params[2].split(" ");
int[] limits = new int[types];
for(int i = 0; i < types; i++){
limits[i] = Integer.parseInt(strs[i]);
}
strs = params[3].split(" ");
int[] values = new int[types];
for(int i = 0; i < types; i++){
values[i] = Integer.parseInt(strs[i]);
}
int[] dp = new int[capacity + 1];
for(int index = 0; index < types; index++){
for(int rest = capacity; rest >= limits[index]; rest--){
dp[rest] = Math.max(dp[rest], values[index] + dp[rest - limits[index]]);
}
}
System.out.println(dp[capacity]);
}
} #include <bits/stdc++.h>
using namespace std;
int main(){
int m,n;
char c;
cin>>m>>c>>n>>c;
int w[n+1], v[n+1];
for(int i=1;i<=n;i++)
cin>>v[i];
cin>>c;
for(int i=1;i<=n;i++)
cin>>w[i];
int dp[n+1][m+1];
memset(dp, 0, sizeof(dp));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
dp[i][j] = dp[i-1][j];
if(j>=v[i])
dp[i][j] = max(dp[i][j], dp[i-1][j-v[i]]+w[i]);
}
cout<<dp[n][m]<<endl;
return 0;
} #include <bits/stdc++.h>
using namespace std;
int main(){
int m,n;
scanf("%d,%d,",&m,&n);
vector<int> num(n,0),value(n,0);
vector<vector<int>> dp(n,vector<int>(m+1,0));
for(int i=0;i<n;i++)
cin>>num[i];
cin.ignore();
for(int i=0;i<n;i++)
cin>>value[i];
for(int j=0;j<=m;j++)
if(j>=num[0])
dp[0][j]=value[0];
for(int i=1;i<n;i++){
for(int j=1;j<=m;j++){
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
if(j>=num[i])
dp[i][j]=max(dp[i][j],dp[i-1][j-num[i]]+value[i]);
}
}
cout<<dp[n-1][m];
return 0;
} 01背包 处理好边界就行了
#include<iostream>
#include<vector>
#include <algorithm>
using namespace std;
int package01(const int & total,vector<int>&weight,vector<int>&value) {
vector<vector<int>>dp(weight.size()+1,vector<int>(total+1,0));
for (int i = 1;i < weight.size();++i) {
for (int j = 1;j <= total ;++j) {
if (weight[i] <=j)
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
else {
dp[i][j] = dp[i - 1][j];
}
}
}
return dp[weight.size()-1][total];
}
int main() {
int total, number;
char c;
cin >> total >>c >> number>>c;
vector<int>weight(number + 1, 0),values(number+1,0);
for (unsigned int i = 0;i < number;++i) {
cin >> weight[i + 1];
}
cin >> c;
for (unsigned int i = 0;i < number;++i) {
cin >> values[i + 1];
}
cout << package01(total,weight,values);
system("pause");
return 0;
}
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String[] strs = in.nextLine().split(",");
int total = Integer.parseInt(strs[0]);
int count = Integer.parseInt(strs[1]);
String[] s1 = strs[2].split(" ");
String[] s2 = strs[3].split(" ");
int[] weight = new int[count];
int[] values = new int[count];
for (int i = 0; i < count; i++) {
weight[i] = Integer.parseInt(s1[i]);
values[i] = Integer.parseInt(s2[i]);
}
int[] dp = new int[total + 1];
for (int i = 1; i <= count; i++) {
for (int j = total; j >= weight[i - 1]; j--) {
dp[j] = Math.max(dp[j], dp[j - weight[i - 1]] + values[i - 1]);
}
}
System.out.println(dp[total]);
}
}
#include <iostream>
using namespace std;
#include <vector>
#include <string>
#include <set>
#include <algorithm>
#include <stack>
#include <map>
#include <list>
#include <ctime>
#include <queue>
#include <unordered_map>
#include <unordered_set>
class Solution {
public:
//递归+剪枝
int dfs(int total, size_t index, vector<int>& cost, vector<int>& values, vector<vector<int>>& record) {
if (total < 0) {
return -1;
}
if (index == cost.size()) {
return 0;
}
if (record[total][index] != -1) {
return record[total][index];
}
int unuse = dfs(total, index + 1, cost, values, record);
int use = dfs(total - cost[index], index + 1, cost, values, record);
if (use != -1) {
use += values[index];
}
record[total][index] = max(use, unuse);
return record[total][index];
}
int getMaxMoney(int total, vector<int>& cost, vector<int>& values) {
vector<vector<int>> record(total + 1, vector<int>(cost.size(), -1));
return dfs(total, 0, cost, values, record);
}
//动态规划
int getMaxMoneyDp(int total, vector<int>& costs, vector<int>& values) {
int n = costs.size();
vector<vector<int>> dp(n + 1, vector<int>(total + 1, 0));
for (int index = n - 1; index >= 0; index--) {
for (int rest = 0; rest <= total; rest++) {
int unuse = dp[index + 1][rest];
int use = rest - costs[index] < 0 ? -1 : dp[index + 1][rest - costs[index]];
if (use != -1) {
use += values[index];
}
dp[index][rest] = max(use, unuse);
}
}
return dp[0][total];
}
};
int main() {
char temp;
int total;
int nums;
cin >> total >> temp >> nums >> temp;
vector<int> cost(nums);
for (int i = 0; i < nums; i++) {
cin >> cost[i];
}
cin >> temp;
vector<int> values(nums);
for (int i = 0; i < nums; i++) {
cin >> values[i];
}
cout << Solution().getMaxMoneyDp(total, cost, values) << endl;
return 0;
} import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
while(in.hasNext()) {
String[] s=in.nextLine().split(",");
int capacity=Integer.valueOf(s[0]);
int num=Integer.valueOf(s[1]);
List<int[]> items=new ArrayList<>();
String[] w = s[2].split(" ");//重量
String[] v = s[3].split(" ");//价值
for(int i=0;i<w.length;i++) {
int[] item=new int[2];
item[0]=Integer.valueOf(w[i]);
item[1]=Integer.valueOf(v[i]);
items.add(item);
}
int res = maxValueByXiaomi(capacity, items);
System.out.println(res);
}
}
//小米资产打包
//总量m=12,种类n=3,重量w分别为4,5,7,价值v分别为500,600,800
public static int maxValueByXiaomi(int capacity,List<int[]> items) {
int n=items.size();
int[][] dp=new int[n+1][capacity+1];//初始化0行0列方便dp
for(int i=1;i<=n;i++) {
for(int j=1;j<=capacity;j++) {
dp[i][j]=(items.get(i-1)[0]>j)?
dp[i-1][j]:Math.max(dp[i-1][j], dp[i-1][j-items.get(i-1)[0]]+items.get(i-1)[1]);
}
}
return dp[n][capacity];
}
} import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] in = sc.nextLine().replaceAll(","," ").split(" ");
int M = Integer.parseInt(in[0]);//载重
int N = Integer.parseInt(in[1]);//种类
int[] m= new int[N], v = new int[N];
for (int i = 0; i < N; i++){
m[i] = Integer.parseInt(in[i + 2]);
v[i] = Integer.parseInt(in[i + 2 + N]);
}
int[] dp = new int[M + 1];
for (int i = 0; i < N; i++){
for (int j = M; j >= m[i]; j--){
dp[j] = Math.max(dp[j], dp[j - m[i]] + v[i]);
}
}
System.out.println(dp[M]);
}
} target,sort,nums,value = input().split(',')
target,sort = int(target.strip()),int(sort.strip())
nums,value = list(map(int,nums.strip().split())),list(map(int,value.strip().split()))
value,nums = [0]+value,[0]+nums
dpc = [0]*(target+1)
for i in range(len(value)):
for j in range(target,-1,-1):
if j>=nums[i]:
dpc[j] = max(dpc[j],dpc[j-nums[i]]+value[i])
print(dpc[-1]) #include <iostream>
(720)#include <vector>
#include <cmath>
using namespace std;
int main(){
int n,m;
char c;
cin>>n>>c>>m>>c;
int *space=new int[m+1],*value=new int[m+1];
for (int i=1;i<=m;i++) cin>>space[i];
cin>>c;
for (int i=1;i<=m;i++) cin>>value[i];
vector<vector<int>> dp(m+1,vector<int>(n+1));
for (int i=1;i<=m;i++)
for (int j=1;j<=n;j++)
dp[i][j]=max(dp[i-1][j],j>=space[i]?dp[i-1][j-space[i]]+value[i]:0);
cout<<dp[m][n];
}
// code2:
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main(){
int n,m;
char c;
cin>>n>>c>>m>>c;
int *space=new int[m],*value=new int[m];
for (int i=0;i<m;i++) cin>>space[i];
cin>>c;
for (int i=0;i<m;i++) cin>>value[i];
int *ans=new int[n+1];
for (int i=0;i<m;i++)
for (int j=n;j>=space[i];j--){
ans[j]=max(ans[j],ans[j-space[i]]+value[i]);
}
cout<<ans[n];
}
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String line = sc.nextLine();
String[] strs = line.split(",");
int c = Integer.parseInt(strs[0]);
int n = Integer.parseInt(strs[1]);
String[] wStr = strs[2].split(" ");
String[] vStr = strs[3].split(" ");
int[] weights = new int[n];
int[] values = new int[n];
for(int i=0;i<n;i++){
weights[i] = Integer.parseInt(wStr[i]);
values[i] = Integer.parseInt(vStr[i]);
}
int[][] dp = new int[n+1][c+1];
for(int i=1;i<=n;i++){
for(int j=1;j<=c;j++){
if(j>=weights[i-1]){
dp[i][j] = Math.max(dp[i-1][j-weights[i-1]]+values[i-1],dp[i-1][j]);
}else
dp[i][j] = dp[i-1][j];
}
}
System.out.println(dp[n][c]);
}
} # 动态规划
space, cls, sizes, values = input().split(",")
space = int(space)
cls = int(cls)
sizes = list(map(int, sizes.strip().split(" ")))
values = list(map(int, values.strip().split(" ")))
dp = [[0]*(space+1) for i in range(cls+1)]
for i in range(1, cls+1):
size = sizes[i-1]
value = values[i-1]
for j in range(0, space+1):
if j >= size:
dp[i][j] = max(dp[i-1][j-size]+value, dp[i-1][j])
else:
dp[i][j] = dp[i-1][j]
print(dp[-1][-1]) total,label,number,value = input().split(',')
number = list(map(int,number.split()))
value = list(map(int,value.split()))
#print(value)
dp = [0]*(int(total)+1)
for i in range(int(label)): # i是种类数
for j in range(len(dp)-1,number[i]-1,-1): #j是number[i]到最大总量之间的数值
dp[j] = max(dp[j],dp[j-number[i]]+value[i])
print(dp[-1])