给定n个空心圆柱体(内半径r,厚度s,高度h),将他们搭起来最大能到达到多高。如果rj+sj>=ri+ri并且ri+si>=rj
才能将木头i放到木头j上面。
sample input
3
1 2 3
2 2 3
5 1 2
output:
6
package 蓝桥杯;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
public class Other动规_圆柱体问题 {
static int N,H;//圆柱体的个数和高度
static cylinder[] a;
static cylinder below;
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner reader=new Scanner(System.in);
N=reader.nextInt();
a=new cylinder[N];
below=new cylinder(0, 1<<30, 0);//将底下的圆柱体初始为内半径为0,厚度为无穷大,高度为0。
H=0;//将高度初始化为0
//读取N个圆柱体的规模
for(int j=0;j<N;j++) {
int r=reader.nextInt();
int s=reader.nextInt();
int h=reader.nextInt();
a[j]=new cylinder(r, s, h);
}
//在算法中切记不要自己的写例如冒泡排序快速排序等算法,用这个方法不容易出错。
List<cylinder> aList=new ArrayList<cylinder>(Arrays.asList(a));//该方法是将数组转化为list,但是注意原数组却不会发生变化
Collections.sort(aList);
int c=0;
for( cylinder e: aList) {
System.out.println(e.toString());//验证排序正确与否,可以去掉
a[c++]=e;
}
int maxH=0;
for(int i=0;i<N;i++) {
H=f(i);
System.out.println(i+" "+H);//验证递归选择的结果,可以去掉
maxH=Math.max(maxH, H);
H=0;
below.r=0;
below.s=1<<30;
}
System.out.println(maxH);
}
//一个拥有自定义排序的类
static class cylinder implements Comparable<cylinder>{
private int r;
private int s;
private int h;
public cylinder(int r,int s,int h) {
this.r=r;
this.s=s;
this.h=h;
}
public int getR() {
return r;
}
public int getS() {
return s;
}
public int getH() {
return h;
}
//实现Comparable接口,重写接口方法
//如果指定的数与参数相等返回0;如果指定的数外半径小于参数返回 -1;
//如果指定的数外半径大于参数返回 1,执行交换,此时升序排序,倒序情况则相反。
@Override
public int compareTo(cylinder next) {
return (this.r+this.s)-(next.getR()+next.getS());
}
@Override
public String toString() {
return "r="+r+",s="+s+",h="+h+"。";
}
}
static int f(int n) {
if(n<0)
return H;
if(a[n].r+a[n].s<=below.r+below.s&&a[n].r+a[n].s>=below.r) {
H+=a[n].h;
below.r=a[n].r;
below.s=a[n].s;
}
return f(n-1);
}
}