一、信息学OJ:1268:【例9.12】完全背包问题
(1)题目描述
设有nn种物品,每种物品有一个重量及一个价值。但每种物品的数量是无限的,同时有一个背包,最大载重量为MM,今从nn种物品中选取若干件(同一种物品可以多次选取),使其重量的和小于等于MM,而价值的和为最大。
【输入】
第一行:两个整数,MM(背包容量,M≤200M≤200)和NN(物品数量,N≤30N≤30);
第2..N+12..N+1行:每行二个整数Wi,CiWi,Ci,表示每个物品的重量和价值。
【输出】
仅一行,一个数,表示最大总价值。
【输入样例】
10 4
2 1
3 3
4 5
7 9
【输出样例】
max=12
(2)代码实现
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
const int maxn = 205;
using namespace std;
int w[maxn],c[maxn],dp[maxn];
int main(){
int V,N;
cin>>V>>N;
for(int i=1;i<=N;i++) cin>>w[i]>>c[i];
for(int i=1;i<=N;i++){
for(int v=w[i];v<=V;v++){
dp[v] = max(dp[v] , dp[v-w[i]] + c[i]);
}
}
cout<<"max="<<dp[V];
return 0;
}
二、信息学OJ:1267:01背包问题
(1)题目描述
一个旅行者有一个最多能装 MM 公斤的背包,现在有 nn 件物品,它们的重量分别是W1,W2,...,WnW1,W2,...,Wn,它们的价值分别为C1,C2,...,CnC1,C2,...,Cn,求旅行者能获得最大总价值。
【输入】
第一行:两个整数,MM(背包容量,M<=200M<=200)和NN(物品数量,N<=30N<=30);
第2..N+12..N+1行:每行二个整数Wi,CiWi,Ci,表示每个物品的重量和价值。
【输出】
仅一行,一个数,表示最大总价值。
【输入样例】
10 4
2 1
3 3
4 5
7 9
【输出样例】
12
(2)代码实现
#include<iostream>
using namespace std;
const int maxn = 1001;
int w[maxn],c[maxn];
int f[maxn];
int main(){
int m,n;
cin>>m>>n;
for(int i=1;i<=n;i++){
cin>>w[i]>>c[i];
}
for(int i=1;i<=n;i++){
for(int j=m;j>=w[i];j--){
f[j] = max(f[j],f[j-w[i]]+c[i]);
}
}
cout<<f[m]<<endl;
return 0;
}
三、蓝桥杯试题 算法提高 搬运冰块
(1)题目描述
问题描述
丑枫接到了一份奇葩的工作:往冰库里搬运冰块.冰库外放着N箱冰块,由于室外温度高,冰块会很快融化,且每箱冰块的融化速度不同.因为每箱冰块的体积,质量不等,把每箱冰块搬运进冰块花费的时间也不同.因此需要合理安排搬运顺序,才能使总的冰块融化量最小.丑枫请你帮忙计算最少的总融化量是多少,以便汇报上司.
输入格式
第一行输入整数N
接下来N行,每行两个整数,分别表示每箱冰块的搬运耗时Ti及融化速度Di.
输出格式
输出最少的总融化量
样例输入
6
6 1
4 5
4 3
6 2
8 1
2 6
样例输出
86
数据规模和约定
2<=N<=100000,1<=Ti<=4000000,1<=Di<=100
样例说明
按照6、2、3、4、1、5的顺序搬运
(2)代码实现
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[] Ti = new int[n];
int[] Di = new int[n];
for(int i = 0 ;i < n ;i++){
Ti[i] = scanner.nextInt();
Di[i] = scanner.nextInt();
}
quickSort(Ti,Di,0,n-1);
long time = 0 ;//int 会出现越界,所以用long
long min = 0 ;
for(int i = n - 1 ;i >= 0 ;i--){
min += time * Di[i];
time += Ti[i];
}
System.out.println(min);
}
public static void quickSort(int[] Ti , int[] Di, int left , int right ) {
if(left >= right ) return ;
double temp = Di[left] * 1.0 / Ti[left];
int start = left ;
int end = right ;
while(start < end ){
while(start < end && Di[end]* 1.0 / Ti[end]>= temp ) end --;
while(start < end && Di[start]* 1.0 / Ti[start]<= temp ) start ++;
if(start < end ){
int tmp = Di[start] ;
Di[start] = Di[end];
Di[end] = tmp;
tmp = Ti[start];
Ti[start] = Ti[ end ];
Ti[end] = tmp;
}
}
int x = Di[left ] ;
Di[left ] = Di[end];
Di[end] = x ;
x = Ti[left ] ;
Ti[left ] = Ti[start];
Ti[start] = x ;
quickSort( Ti, Di, left ,end - 1 );
quickSort( Ti, Di, end + 1 ,right);
}
}