2022-02-10每日刷题打卡

一、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);
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值