塔圆柱问题(Java)

给定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);
	}

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值