一、信息学OJ:1270:【例9.14】混合背包
(1)问题描述
一个旅行者有一个最多能装V公斤的背包,现在有n件物品,它们的重量分别是W1,W2,...,WnW1,W2,...,Wn,它们的价值分别为C1,C2,...,CnC1,C2,...,Cn。有的物品只可以取一次(01背包),有的物品可以取无限次(完全背包),有的物品可以取的次数有一个上限(多重背包)。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
【输入】
第一行:二个整数,M(背包容量,M<=200),N(物品数量,N<=30);
第2..N+1行:每行三个整数Wi,Ci,PiWi,Ci,Pi,前两个整数分别表示每个物品的重量,价值,第三个整数若为0,则说明此物品可以购买无数件,若为其他数字,则为此物品可购买的最多件数(PiPi)。
【输出】
仅一行,一个数,表示最大总价值。
【输入样例】
10 3
2 1 0
3 3 1
4 5 4
【输出样例】
11
【提示】
选第一件物品1件和第三件物品2件
(2)代码实现
#include<cstdio>
using namespace std;
const int N=201;
int qread () {
int x=0,f=1;
char ch=getchar();
while (ch>'9'||ch<'0') {
if(ch=='-') f=-1;
ch=getchar();
}
while (ch>='0'&&ch<='9') {
x=(x<<3)+(x<<1)+ch-48;
ch=getchar();
}
return x*f;
}
int i,j,m,n,wi,ci,ti,k,f[N]={0};
int main () {
m=qread();n=qread();
for(i=1;i<=n;i++) {
wi=qread();ci=qread();ti=qread();
if(ti==0) {
for(j=wi;j<=m;j++)
if(f[j]<f[j-wi]+ci) f[j]=f[j-wi]+ci;
}
for(k=1;k<=ti;k++)
for(j=m;j>=wi;j--)
if(f[j]<f[j-wi]+ci) f[j]=f[j-wi]+ci;
}
printf("%d",f[m]);
return 0;
}
二、信息学OJ:1269:【例9.13】庆功会
(1)问题描述
为了庆贺班级在校运动会上取得全校第一名成绩,班主任决定开一场庆功会,为此拨款购买奖品犒劳运动员。期望拨款金额能购买最大价值的奖品,可以补充他们的精力和体力。
【输入】
第一行二个数n(n≤500)n(n≤500),m(m≤6000)m(m≤6000),其中nn代表希望购买的奖品的种数,mm表示拨款金额。
接下来nn行,每行33个数,vv、ww、ss,分别表示第I种奖品的价格、价值(价格与价值是不同的概念)和能购买的最大数量(买00件到ss件均可),其中v≤100v≤100,w≤1000w≤1000,s≤10s≤10。
【输出】
一行:一个数,表示此次购买能获得的最大的价值(注意!不是价格)。
【输入样例】
5 1000
80 20 4
40 50 9
30 50 7
40 30 6
20 20 1
【输出样例】
1040
(2)代码实现
复制代码到粘帖板
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
const int maxn = 6005;
using namespace std;
int w[maxn],c[maxn],p[maxn],dp[maxn];
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>w[i]>>c[i]>>p[i];
for(int i=1;i<=n;i++){
for(int j=m;j>=0;j--){
for(int k=0;k<=p[i];k++){
if(j - k * w[i] < 0) break;
dp[j] = max(dp[j],dp[j-k*w[i]]+k*c[i]);
}
}
}
cout<<dp[m];
return 0;
}
三、蓝桥杯试题 历届真题 递增三元组【第九届】【省赛】【B组】
(1)问题描述
资源限制
时间限制:1.0s 内存限制:256.0MB
给定三个整数数组
A = [A1, A2, ... AN],
B = [B1, B2, ... BN],
C = [C1, C2, ... CN],
请你统计有多少个三元组(i, j, k) 满足:
1. 1 <= i, j, k <= N
2. 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
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
注意:
main函数需要返回0;
只使用ANSI C/ANSI C++ 标准;
不要调用依赖于编译环境或操作系统的特殊函数。
所有依赖的函数必须明确地在源文件中 #include <xxx>
不能通过工程设置而省略常用头文件。
提交程序时,注意选择所期望的语言类型和编译器类型。
(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);
}
}