题:
https://leetcode-cn.com/problems/filling-bookcase-shelves/
解1(超时):
public static int minHeightShelves(int[][] books, int shelf_width) {
int[] minHigh = new int[]{Integer.MAX_VALUE};
dfs(minHigh,0,books,shelf_width,0);
return minHigh[0];
}
/**
* 超时解法:
* 深搜,每层放一本书、两本书、...直到该层厚度为shelf_width
* @param minHigh 最小整体高度
* @param currentHigh 当前整体高度
* @param books 书的数组
* @param shelf_width 书架宽度
* @param curIndex 当前数组下标,还没放的第一本书
*/
public static void dfs(int[] minHigh,int currentHigh,int[][] books , int shelf_width , int curIndex){
if(curIndex == books.length){
minHigh[0] = Math.min(minHigh[0],currentHigh);
return;
}
int curWidth = 0; // 当前层宽度
int currentLevelHigh = 0; // 当前层高度
for(int i = curIndex ; i < books.length ; i++){
curWidth+=books[i][0];
if(curWidth > shelf_width)
break;
else{
currentLevelHigh = Math.max(currentLevelHigh,books[i][1]); // 更新当前层最高的高度
dfs(minHigh,currentHigh+currentLevelHigh,books,shelf_width,i+1);
}
}
}
解2(动态规划):
public static int minHeightShelves(int[][] books, int shelf_width) {
/**
* dp表示 只考虑前i本书的时候,书架最小高度
* */
int[] dp = new int[books.length];
dp[0] = books[0][1];
//dp[1] = books[0][0]+books[0][1] > shelf_width?dp[0]+books[1][1]:Math.max(dp[0],books[1][1]);
for(int i = 1 ; i < books.length ; i++){
dp[i] = dp[i-1] + books[i][1];
int levelWidth = books[i][0];
int levelHigh = books[i][1];
for(int j = i - 1 ; j >= 0 ; j--){
levelWidth+=books[j][0];
if(levelWidth <= shelf_width){
levelHigh = Math.max(levelHigh,books[j][1]);
dp[i] = j-1>=0?Math.min(dp[i],dp[j-1]+levelHigh):levelHigh;
}else break;
}
}
return dp[books.length-1];
}