一、AcWing 4. 多重背包问题
(1)题目描述
有 NN 种物品和一个容量是 VV 的背包。
第 ii 种物品最多有 sisi 件,每件体积是 vivi,价值是 wiwi。
求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。
输出最大价值。
输入格式
第一行两个整数,N,VN,V,用空格隔开,分别表示物品种数和背包容积。
接下来有 NN 行,每行三个整数 vi,wi,sivi,wi,si,用空格隔开,分别表示第 ii 种物品的体积、价值和数量。
输出格式
输出一个整数,表示最大价值。
数据范围
0<N,V≤1000<N,V≤100
0<vi,wi,si≤1000<vi,wi,si≤100
输入样例
4 5
1 2 3
2 4 1
3 4 3
4 5 2
输出样例:
10
(2)代码实现
import java.util.Scanner;
public class Main {
static int N = 105;
static int f[][] = new int[N][N];
static int w[] = new int[N];
static int v[] = new int[N];
static int s[] = new int[N];
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
for(int i = 1; i <= n ; i++) {
int a = scanner.nextInt();
int b = scanner.nextInt();
int c = scanner.nextInt();
s[i] = c;v[i] = a;w[i] = b;
}
for(int i = 1; i <= n ; i ++) {
for(int j = 0 ; j <= m ; j ++) {
f[i][j] = f[i-1][j];
for(int k = 1; k <= s[i]; k++) {
if(j>=k*v[i]) {
f[i][j] = Math.max(f[i][j], f[i-1][j-k*v[i]]+k*w[i]);
}
}
}
}
System.out.println(f[n][m]);
}
}
二、AcWing 5. 多重背包问题 II
(1)题目描述
有 NN 种物品和一个容量是 VV 的背包。
第 ii 种物品最多有 sisi 件,每件体积是 vivi,价值是 wiwi。
求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。
输出最大价值。
输入格式
第一行两个整数,N,VN,V,用空格隔开,分别表示物品种数和背包容积。
接下来有 NN 行,每行三个整数 vi,wi,sivi,wi,si,用空格隔开,分别表示第 ii 种物品的体积、价值和数量。
输出格式
输出一个整数,表示最大价值。
数据范围
0<N≤10000<N≤1000
0<V≤20000<V≤2000
0<vi,wi,si≤20000<vi,wi,si≤2000
提示:
本题考查多重背包的二进制优化方法。
输入样例
4 5
1 2 3
2 4 1
3 4 3
4 5 2
输出样例:
10
(2)代码实现
import java.util.Scanner;
public class Main {
static int N = 2010,M = 12000;//2000是体积,12000是分解后的物品的个数
static int f[] = new int[N];
static int v[] = new int[M];
static int w[] = new int[M];
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
int cnt = 0;
while(n-->0) {
int a = scanner.nextInt();
int b = scanner.nextInt();
int s = scanner.nextInt();
int k = 1;
while(s>=k) {
cnt++;
v[cnt] = k*a;
w[cnt] = k*b;
s-=k;
k <<=1;
}
if(s>0) {
cnt++;
v[cnt] = s*a;
w[cnt] = s*b;
}
}
n = cnt;
for(int i = 1; i <= n ; i ++) {
for(int j = m;j>=v[i];j--) {
f[j] = Math.max(f[j], f[j-v[i]]+w[i]);
}
}
System.out.println(f[m]);
}
}
三、 蓝桥杯 第六题:递增三元组
(1)题目描述
给定三个整数数组
A = [A1, A2, … AN],
B = [B1, B2, … BN],
C = [C1, C2, … CN],
请你统计有多少个三元组(i, j, k) 满足:
1 <= i, j, k <= N
Ai < Bj < Ck
【输入格式】
第一行包含一个整数N。
第二行包含N个整数A1, A2, … AN。
第三行包含N个整数B1, B2, … BN。
第四行包含N个整数C1, C2, … CN。
对于30%的数据,1 <= N <= 100
对于60%的数据,1 <= N <= 1000
对于100%的数据,1 <= N <= 100000 0 <= Ai, Bi, Ci <= 100000
【输出格式】
一个整数表示答案
【输入样例】
3
1 1 1
2 2 2
3 3 3
【输出样例】
27
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。
(2)代码实现
import java.util.Arrays;
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] A = new int[n];
int[] B = new int[n];
int[] C = new int[n];
for(int i=0;i<n;i++)
A[i] = in.nextInt();
for(int i=0;i<n;i++)
B[i] = in.nextInt();
for(int i=0;i<n;i++)
C[i] = in.nextInt();
Arrays.sort(A);
Arrays.sort(B);
Arrays.sort(C);
int ans=0;
for(int i=0;i<n;i++) {
for(int j=0;j<n;j++)
if(A[i]<B[j]) {
int l=0,r=n-1;
while(l<=r){
int m = (l+r)/2;
if(C[m]>B[j]) r= m-1;
else l = m +1;
}
ans+=n-l;
}
}
System.out.println(ans);
}
}