动态规划
一、题目描述
题目链接
这个题目的描述也是让人醉了
站在上面的人满足的条件是(对比它下面的人):
- 体重小,身高相同或身高小
- 体重相同,身高相同
二、解题丝路
- 最初看题目,两种判断条件着实有点发懵,没有顺序可言,用过DFS,最终超时;
- 当根据其中一个判断条件,确定每个人(role)相对固定的顺序(即先根据体重排序),再找 最多能排多少层,就只看身高这一个条件了,此时,可以使用DP
- 开始并没有真正看懂条件,对于体重相同的情况比较模糊,并没有对排序时对体重相同的情况作出相应处理,但是根据整体思路写出代码,后经过调试才真正的看懂题目条件
- “体重小,身高相同或身高小” ,体重从大到小排序,求 身高的最长递减(或相等)子序列
- “体重相同,身高相同” ,体重相同时,根据身高排序,身高从小到大;这种排序方法,在求 身高的最长递减(或相等)子序列时,并不会出现“体重相同,身高小”的情况
- 先根据体重排序,从大到小;体重相同时,根据身高排序,身高从小到大
- 求身高的 最长递减(或相等)子序列的长度
- 确定状态方程:F(i)表示 以第 i 个人结尾的 最长递减子序列的长度
- 状态转移方程:通过 j 遍历第 0 — > i - 1个人的所有状态,如果 tall[ j ] >= tall[ i ],F(i)= max(F(i),F(j)+ 1);
- 确定最初状态:所有的F(i)= 1
- 得到最终结果:取最大的F(i)
三、代码实现
import java.util.*;
public class Main {
static class Role{
int id;
int weight;
int tall;
public Role(int id, int weight, int tall) {
this.id = id;
this.weight = weight;
this.tall = tall;
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while(scanner.hasNext()) {
int n = scanner.nextInt();
Role[] role = new Role[n];
for (int i = 0; i < n; i++) {
int id = scanner.nextInt();
int w = scanner.nextInt();
int t = scanner.nextInt();
role[i] = new Role(id, w, t);
}
Arrays.sort(role, new Comparator<Role>() {
@Override
public int compare(Role o1, Role o2) {
// 这个if语句就是对 “体重相同,身高相同” 作出的处理
if(o1.weight == o2.weight){
return o1.tall - o2.tall;
}
return o2.weight - o1.weight;
}
});
int[] F = new int[n];
F[0] = 1;
for (int i = 1; i < n; i++) {
F[i] = 1;
Role roleI = role[i];
for (int j = i - 1; j >= 0; j--) {
Role roleJ = role[j];
if(roleI.tall <= roleJ.tall){
F[i] = Math.max(F[i], F[j] + 1);
}
}
}
int max = 0;
for (int i = 0; i < n; i++) {
max = Math.max(max, F[i]);
}
System.out.println(max);
}
}
}
走遍四海,还是威海
山东威海