目录
一、打水问题
题目描述
N个人要打水,有M个水龙头,第i个人打水所需时间为Ti,请安排一个合理的方案使得所有人的等待时间之和尽量小。
提示
一种最佳打水方案是,将N个人按照Ti从小到大的顺序依次分配到M个龙头打水。
例如样例中,Ti从小到大排序为1,2,3,4,5,6,7,将他们依次分配到3个龙头,则去龙头一打水的为1,4,7;去龙头二打水的为2,5;去第三个龙头打水的为3,6。
第一个龙头打水的人总等待时间 = 0 + 1 + (1 + 4) = 6
第二个龙头打水的人总等待时间 = 0 + 2 = 2
第三个龙头打水的人总等待时间 = 0 + 3 = 3
所以总的等待时间 = 6 + 2 + 3 = 11输入
第一行两个正整数N M 接下来一行N个正整数Ti。
N,M< =1000,Ti< =1000输出
最小的等待时间之和。(不需要输出具体的安排方案)
样例输入
7 3 3 6 1 4 2 5 7样例输出
11
对题目理解很重要!这个题其实就是将打水人的时间做个排序,在分别安排到水龙头就行了。就是一种贪心的思想,对于最后被安排(水龙头个数)的M个人,是不用加入计算的(题目中只让求等待时间),其余看代码中解析。
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n=sc.nextInt();
int m=sc.nextInt();
int[] arr=new int[n];
for(int i=0;i<n;i++) {
arr[i]=sc.nextInt();
}
Arrays.sort(arr);
int[] num=new int[m];
int sum=0;
int j=0;
while (j<n-m){ //最后一个人后面没人等待了 所以每个水龙头的最后一个人的时间都不用去加
for (int i = 0; i < m&&j<n-m; i++,j++) { // j为打水的人
temp[i]+=a[j];//第二个人打水人等待的时间为第一个打水人的打水时间
sum+=temp[i]; //第n个人等待的打水时间为前面n-1个人的打水时间和
}
}
System.out.println(sum);
}
}
二、夺宝奇兵
题目描述
在一座山上,有很多很多珠宝,它们散落在山底通往山顶的每条道路上,不同道路上的珠宝的数目也各不相同.下图为一张藏宝地图:
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
”夺宝奇兵”从山下出发,到达山顶,如何选路才能得到最多的珠宝呢?在上图所示例子中,按照5-> 7-> 8-> 3-> 7的顺序,将得到最大值30输入
第一行正整数N(100> =N> 1),表示山的高度
接下来有N行非负整数,第i行有i个整数(1< =i< =N),表示山的第i层上从左到右每条路上的珠宝数目输出
一个整数,表示从山底到山顶的所能得到的珠宝的最大数目.
样例输入
5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5样例输出
30
这个题是一个dp问题,对于dp问题,我们最主要的是要了解这个过程,题目中的山其实并不是直角三角形的,而是像“杨辉三角”那样的,代码如下:
import java.util.*;
public class Main{
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[][] dp = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) {
dp[i][j] = sc.nextInt();
}
}
for (int i = n-2; i >= 0; i--) {
for (int j = 0; j <= i; j++) {
dp[i][j] += Math.max(dp[i+1][j],dp[i+1][j+1]);
}
}
System.out.println(dp[0][0]);
}
}
三、调手表
【题目】小明买了块高端大气上档次的电子手表,他正准备调时间呢。
在 M78 星云,时间的计量单位和地球上不同,M78 星云的一个小时有 n 分钟。
大家都知道,手表只有一个按钮可以把当前的数加一。在调分钟的时候,如果当前显示的数是 0 ,那么按一下按钮就会变成 1,再按一次变成 2 。如果当前的数是 n−1,按一次后会变成 0。
作为强迫症患者,小明一定要把手表的时间调对。如果手表上的时间比当前时间多 1,则要按 n - 1 次加一按钮才能调回正确时间。
小明想,如果手表可以再添加一个按钮,表示把当前的数加 k 该多好啊......
他想知道,如果有了这个 +k 按钮,按照最优策略按键,从任意一个分钟数调到另外任意一个分钟数最多要按多少次。
注意,按 +k按钮时,如果加 k 后数字超过 n-1,则会对 n 取模。
比如,n=10, k=6 的时候,假设当前时间是 0,连按 2 次 +k 按钮,则调为 2。
输入描述
一行两个整数 n(意义如题)。
输出描述
输出一行一个整数,表示按照最优策略按键,从一个时间调到另一个时间最多要按多少次。
在这个题中,如果想达到题目最终的结果,有两种情况:第一种,直接通过+k就能达到需求时间,第二种,如果无法只用+k实现,那么实现时间的上一步绝对是+1【且+1的数量一定小于k】,代码如下:
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int k=sc.nextInt();
int[] arr=new int[n];
for (int i=1;i<n;i++){
if (i%k==0){
arr[i]=i/k;
}else{
arr[i]=arr[i-1]+1;
for ( int j = 1; j <= arr[i-1]+1 ; j++ ) {
if ( ( k * j ) % n == i ) {
arr[i] = j;
break;
}
}
}
}
Arrays.sort(arr);
System.out.println(arr[n-1]);
}
}
四、一步之遥
【题目】从昏迷中醒来,小明发现自己被关在 X 星球的废矿车里。 矿车停在平直的废弃的轨道上。 他的面前是两个按钮,分别写着 “F” 和 “B” 。
小明突然记起来,这两个按钮可以控制矿车在轨道上前进和后退。 按 F,会前进 97 米。按 B 会后退127 米。 透过昏暗的灯光,小明看到自己前方 1 米远正好有个监控探头。 他必须设法使得矿车正好停在摄像头的下方,才有机会争取同伴的援助。 或许,通过多次操作 F 和 B 可以办到。
矿车上的动力已经不太足,黄色的警示灯在默默闪烁... 每次进行 F 或 B 操作都会消耗一定的能量。 小明飞快地计算,至少要多少次操作,才能把矿车准确地停在前方 1 米远的地方。
请问为了达成目标,最少需要操作的次数是多少。
这个题也是理解题,只要理解题目就很简单了,我们可以假设现在位置为0,然后进行加减完成位置变成1,这样就可以实现了,代码如下:
public class Main{
public static void main(String[] args) {
System.out.println(ans(0));
}
private static int ans(int n) {
int sum=0;
for(int i=0;i<1000;i++) {
for(int j=0;j<1000;j++) {
if(sum+97*i-127*j==1) {
return i+j;
}
}
}
return sum;
}
}