话不多说直接上题
分析一下,题目要求的是能让所有的箱子竖着堆起来
下面的箱子要比上面的箱子的三维正经的都要大
很明显也就是求一个箱子的摆放序列,使得三维递增
这很明显是一个最长递增子序列问题,那么我们可以
怎么做呢,因为数据量不大,只有3000,直接n^2的dp
就行,先将所有的箱子按照第一维升序排序(很重要)
然后对每一个箱子i,求它作为最下面的时候的最大高度
需要注意的是必须要排序,不然的话此时i作为最下面
不一定是最优的~
~应该也可以不排序,只不过这时候要对于每个箱子遍历所有的其他箱子~~
于是就有以下的转移方程dp[i] = max(dp[i],dp[j]+hi)对于所有的
三维都小于i的j的箱子
class Solution {
public int pileBox(int[][] box) {
Arrays.sort(box,(int[] a,int[] b)->{
return a[0]-b[0];
});
int[] dp = new int[box.length];
int ans=0;
for(int i=0; i<box.length; i++){
dp[i]=box[i][2];
for(int j=0; j<i; j++){
if(judge(box[j],box[i]))
dp[i]=Math.max(dp[i],dp[j]+box[i][2]);
}
}
for(int i:dp){
ans=Math.max(ans,i);
}
return ans;
}
boolean judge(int[] a,int[] b){
return b[0]>a[0]&&b[1]>a[1]&&b[2]>a[2];
}
}
很明显,这里要求的是身高体重递增,也是求最长上升子序列的长度
但是不同的是数据量是10^4, 直接n^2的dp的话会在leetcode超时
于是就用到了LIS的优化,优化的过程是,不断的去降低长度为i的
最下面的一个人的体重和身高,这样子下一次进来人的时候,给它
放到最合适它的那一组就可以了,但是要注意的就是,因为这里要求
的是所有的人的体重身高都要增加,所以排序的时候,先按体重升序
然后按照身高降序排列。 于是就有转移方程,假设当前的最长的子序列
长度是maxlen, 则当遇到一个新的人i,由前面的排序过程,可以知道不会
被后面身高相同的人更新,因为它更轻,于是有,if weight[i]>dp[maxlen]
那么dp[maxlen+1]=weight[i],因为它比前面最长的队的人的身高体重都大
else 就找第一个j st.dp[j]>=wight[i].有这个过程可以知道,dp数组是单调非降得
甚至是单调递增得,所以这个过程就是可以用二分查找来做,所以最后得总复杂就是o(nlogn)
import java.util.*;
class Solution {
public int bestSeqAtIndex(int[] height, int[] weight) {
//最长递增子序列
int[] dp = new int[height.length+1];
List<int[]> person = new ArrayList(height.length);
for(int i=0; i<height.length; i++){
person.add(new int[]{height[i],weight[i]});
}
person.sort((int[]a,int[]b)->{
return a[0]==b[0]?b[1]-a[1]:a[0]-b[0];
});
int maxlen=0;
int pos=0;
for(int i=0; i<height.length; i++){
if(person.get(i)[1]>dp[maxlen])//可以直接更新
dp[++maxlen]=person.get(i)[1];
else if(person.get(i)[1]<dp[maxlen]){
pos=binarySearch(dp,1,maxlen,person.get(i)[1]);
dp[pos]=person.get(i)[1];
}
}
return maxlen;
}
public int binarySearch(int[]dp,int beg,int end,int tatget){
int mid=0;
while(beg<end){
//查找的是第一个大于等于他的
//不能查找第一个大于他的,因为如果查找第一个大于他的
//可能这个传递过来的是刚好由这个相等传递过来的
//那么此时这个体重不能更新这一个
mid=beg+((end-beg)>>1);
if(dp[mid]>=tatget){
end=mid;
//这里是要保留右边的,也就是第一个大于等于的
}
else{
beg=mid+1;
}
}
return end;
}
}