PTA---贪心算法
作者:互联网
文章目录
7-1 装箱问题
import java.util.Scanner;
public class Program1 {
public static void main(String[] args) {
int N;
Scanner in = new Scanner(System.in);
N = in.nextInt();
int []things = new int[N];
//最多有N个箱子
int []box = new int[N];
//记录最大所需箱子数
int maxBox = 0;
//对每个物品进行顺序装箱
for(int i = 0;i < N;i++){
//物品输入
things[i] = in.nextInt();
//存箱模拟
int index = 0;
while (box[index] + things[i] > 100 ){
index++;
}
box[index] += things[i];
System.out.println(things[i] + " " + (index + 1));
if(maxBox < index + 1){
maxBox = index + 1;
}
}
System.out.println(maxBox);
}
}
7-2 月饼
7-2 月饼 (25 分)
月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼。现给定所有种类月饼的库存量、总售价、以及市场的最大需求量,请你计算可以获得的最大收益是多少。
注意:销售时允许取出一部分库存。样例给出的情形是这样的:假如我们有 3 种月饼,其库存量分别为 18、15、10 万吨,总售价分别为 75、72、45 亿元。如果市场的最大需求量只有 20 万吨,那么我们最大收益策略应该是卖出全部 15 万吨第 2 种月饼、以及 5 万吨第 3 种月饼,获得 72 + 45/2 = 94.5(亿元)。
输入格式:
每个输入包含一个测试用例。每个测试用例先给出一个不超过 1000 的正整数 N 表示月饼的种类数、以及不超过 500(以万吨为单位)的正整数 D 表示市场最大需求量。随后一行给出 N 个正数表示每种月饼的库存量(以万吨为单位);最后一行给出 N 个正数表示每种月饼的总售价(以亿元为单位)。数字间以空格分隔。
输出格式:
对每组测试用例,在一行中输出最大收益,以亿元为单位并精确到小数点后 2 位
这题对java超级不友好,使用java自带的快排容易超时,而且有些还不支持。。。。。无语
Java参考代码:
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class Program2 {
/**
* 解题思路:根据月饼数量和售价比值进行选择,每次选择比值最小的总收益最大
*
*/
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int N = in.nextInt(); //月饼种类
int D = in.nextInt(); //总库存
//二维数组分别存储月饼库存,总售价
double [][]numValRate = new double[N][2];
for(int i = 0;i < N;i++){
numValRate[i][0] = in.nextDouble();
}
for(int i = 0;i < N;i++){
numValRate[i][1] = in.nextDouble();
}
//根据比值进行从小到大排序
// 下面这个排序在PTA上会超时原因不明
//Arrays.sort(numValRate, Comparator.comparingDouble(o -> ((double) o[0] / o[1])));
Arrays.sort(numValRate, new Comparator<double[]>() {
@Override
public int compare(double[] o1, double[] o2) {
if(o1[0] / o1[1] - o2[0] / o2[1] >= 0){
return 1;
}else {
return -1;
}
}
});
double sumVal = 0; //总收益
int i = 0;
while (!(D <= 0 || i >= N)){
if(D >= numValRate[i][0]){
D -= numValRate[i][0];
sumVal += numValRate[i][1];
}else {
sumVal += ((double)D / numValRate[i][0]) * numValRate[i][1];
D = 0;
}
i++;
}
System.out.printf("%.2f\n",sumVal);
}
}
可提交的C代码:
//贪心月饼问题
#include <stdio.h>
#include <stdlib.h>
int cmp(const void *_a, const void *_b) {
double *a = (double *) (_a);
double *b = (double *) (_b);
if (a[0] / a[1] - b[0] / b[1] >= 0) {
return 1;
} else {
return -1;
}
}
int main() {
/**
* 解题思路:根据月饼数量和售价比值进行选择,每次选择比值最小的总收益最大
*
*/
int N; //月饼种类
scanf("%d", &N);
int D; //总库存
scanf("%d", &D);
//二维数组分别存储月饼库存,总售价
double numValRate[N][2];
for (int i = 0; i < N; i++) {
scanf("%lf", &numValRate[i][0]);
}
for (int i = 0; i < N; i++) {
scanf("%lf", &numValRate[i][1]);
}
qsort(numValRate, sizeof(numValRate) / sizeof(numValRate[0]), sizeof(numValRate[0]), cmp);
double sumVal = 0; //总收益
int i = 0;
while (!(D <= 0 || i >= N)) {
if (D >= numValRate[i][0]) {
D -= numValRate[i][0];
sumVal += numValRate[i][1];
} else {
sumVal += ((double) D / numValRate[i][0]) * numValRate[i][1];
D = 0;
}
i++;
}
printf("%.2f\n", sumVal);
}
##7-3 汽车加油问题 (25 分)
题目来源:王晓东《算法设计与分析》
一辆汽车加满油后可行驶 n公里。旅途中有若干个加油站。设计一个有效算法,指出应 在哪些加油站停靠加油,使沿途加油次数最少。
输入格式:
第一行有 2 个正整数n和 k(k<=1000 ),表示汽车加满油后可行驶n公里,且旅途中有 k个加油站。 第二行有 k+1 个整数,表示第 k 个加油站与第k-1 个加油站之间的距离。 第 0 个加油站表示出发地,汽车已加满油。 第 k+1 个加油站表示目的地。
输出格式:
输出最少加油次数。如果无法到达目的地,则输出“No Solution!”。
import java.util.Scanner;
public class Program3 {
//贪心算法:汽油加油问题
//思路:只要剩余的油能够到达下一站就不停车,否则停车加油
static final String NoSolution = "No Solution!";
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt(); //油箱总量
int k = in.nextInt(); //目的地数量
int []pos = new int[k + 1]; //加油站信息
for(int i = 0;i < k + 1;i++){
pos[i] = in.nextInt();
}
int minTime = 0;
int fuelTank = n;
for(int i = 0;i < k + 1;i++){
//油量充足
if(pos[i] <= fuelTank){
fuelTank -= pos[i];
}else if(pos[i] > fuelTank && fuelTank == n){
//满油箱量不足到达
minTime = -1;
break;
}else {
//加满油
fuelTank = n;
fuelTank -= pos[i];
minTime++;
}
}
if(minTime >= 0){
System.out.println(minTime);
}else {
System.out.println(NoSolution);
}
}
}
/*
7 7
1 2 3 4 5 1 6 6
*/
7-4 活动选择问题
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class Program4 {
//贪心:获得选择问题
//思路:根据活动最快结束时间进行选择,开始时间为上一个活动的结束时间
//初始开始时间为0
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int [][]active = new int[n][2];
for(int i = 0;i < n;i++){
active[i][0] = in.nextInt();
active[i][1] = in.nextInt();
}
//排序,根据最快结束时间进行排序,从小到大排序
Arrays.sort(active, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[1] - o2[1];
}
});
int times = 0; //最多活动次数
int startTime = 0;
int index = 0;
while (index < n){
if(startTime <= active[index][0]){
times++;
startTime = active[index][1];
}
index++;
}
System.out.println(times);
}
}
/*
11
3 5
1 4
12 14
8 12
0 6
8 11
6 10
5 7
3 8
5 9
2 13
*/
标签:Scanner,月饼,int,double,PTA,---,++,numValRate,贪心 来源: https://blog.csdn.net/wr456wr/article/details/120883415