题目
有N个积木,变长为Li,每个高度为1,每个重量为Wi
要求:
- 严格保证变长大的叠在边长小的上面
- 每个积木只能承受自身大小7倍以内的重量,所以其上所有积木重量综合不能超过这么多
- 问最高能搭多高的积木
输入:
10 # 积木个数N
1 2 3 4 5 6 7 8 9 10 # 各积木边长
1 1 1 1 1 1 1 1 1 10 # 各积木重量
算法
public class class4 {
static class Block {
int id;
int Li;
int Wi;
public Block(int id, int li, int wi) {
this.id = id;
Li = li;
Wi = wi;
}
}
static class Way{
int curTotalWi;
int maxWi;
int curHi;
List<Integer> bidList = new ArrayList<>();
public Way(int curTotalWi, int maxWi, int curHi) {
this.curTotalWi = curTotalWi;
this.maxWi = maxWi;
this.curHi = curHi;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
if (n < 1) {
return;
}
int[][] arr = new int[n][2];
ArrayList<Block> blocks = new ArrayList<>();
for (int i = 0; i < arr.length; i++) {
arr[i][0] = sc.nextInt();
}
for (int i = 0; i < arr.length; i++) {
arr[i][1] = sc.nextInt();
}
for (int i = 0; i < arr.length; i++) {
Block block = new Block(i + 1, arr[i][0], arr[i][1]);
blocks.add(block);
}
Collections.sort(blocks, (o1, o2) -> {
if (o1.Li < o2.Li) return -1;
if (o1.Li > o2.Li) return 1;
return 0;
});
Way[] ways = new Way[n];
ways[0] = new Way(blocks.get(0).Wi,blocks.get(0).Wi,1);
for (int i =1; i < n; i++) {
if(blocks.get(i).Wi*7>=ways[i-1].curTotalWi){
int maxWi = blocks.get(i).Wi>ways[i-1].maxWi?blocks.get(i).Wi:ways[i-1].maxWi;
ways[i] = new Way(ways[i-1].curTotalWi+blocks.get(i).Wi,maxWi,ways[i-1].curHi+1);
ways[i].bidList.add(blocks.get(i).id);
}else if(blocks.get(i).Wi<ways[i-1].maxWi&&blocks.get(i).Wi*7>=ways[i-1].curTotalWi-ways[i-1].maxWi){
int newMax = 0;
for(Iterator<Integer> it = ways[i-1].bidList.iterator();it.hasNext();){
Integer integer = it.next();
if(integer==ways[i-1].maxWi){
it.remove();
}else if(integer>newMax){
newMax = integer;
}
}
ways[i-1].bidList.add(blocks.get(i).id);
ways[i] = new Way(ways[i-1].curTotalWi+blocks.get(i).Wi-ways[i-1].maxWi,newMax,ways[i-1].curHi);
ways[i].bidList = new ArrayList<>(ways[i-1].bidList);
}else {
ways[i] = ways[i-1];
}
}
System.out.println(ways[n-1].curHi);
}
}
- 对输入的积木边长按大小排序,得到数组
blocks
- 定义当前已经搭好的积木堆总重量,积木堆中最大重量积木大小,积木堆高度
- 依次从数组
blocks
取积木,判断当前积木能否承受当前已搭好积木重量
3.1 如果能,直接加入积木堆,高度加1
3.2 如果不能,判断当前积木堆中最重积木是否比当前积木重,且剔除这个最重积木之后当前积木能否承受积木堆重量,能则剔除最重积木并替换当前积木进入积木堆,否则抛弃当前积木 - 遍历完成后最终积木堆高度为当前积木堆高度