叠罗汉(动态规划)

动态规划
一、题目描述
题目链接

这里是引用
在这里插入图片描述

这个题目的描述也是让人醉了
站在上面的人满足的条件是(对比它下面的人):

  1. 体重小,身高相同或身高小
  2. 体重相同,身高相同

二、解题丝路

在这里插入图片描述

  1. 最初看题目,两种判断条件着实有点发懵,没有顺序可言,用过DFS,最终超时;
  2. 根据其中一个判断条件,确定每个人(role)相对固定的顺序(即先根据体重排序),再找 最多能排多少层,就只看身高这一个条件了,此时,可以使用DP
  3. 开始并没有真正看懂条件,对于体重相同的情况比较模糊,并没有对排序时对体重相同的情况作出相应处理,但是根据整体思路写出代码,后经过调试才真正的看懂题目条件
  4. “体重小,身高相同或身高小” ,体重从大到小排序,求 身高的最长递减(或相等)子序列
  5. “体重相同,身高相同” ,体重相同时,根据身高排序,身高从小到大;这种排序方法,在求 身高的最长递减(或相等)子序列时,并不会出现“体重相同,身高小”的情况
  1. 先根据体重排序,从大到小;体重相同时,根据身高排序,身高从小到大
  2. 身高的 最长递减(或相等)子序列的长度
  3. 确定状态方程:F(i)表示 以第 i 个人结尾的 最长递减子序列的长度
  4. 状态转移方程:通过 j 遍历第 0 — > i - 1个人的所有状态,如果 tall[ j ] >= tall[ i ],F(i)= max(F(i),F(j)+ 1);
  5. 确定最初状态:所有的F(i)= 1
  6. 得到最终结果:取最大的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);
        }
    }
}

走遍四海,还是威海
山东威海

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

威少总冠军

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值