Sorting_Searching 叠罗汉 @CareerCup

本文探讨解决叠罗汉问题的方法,包括回溯算法和最长递增子序列(LIS)算法的应用。通过实例解析,详细阐述了如何利用这两种算法找出叠罗汉中最大可能的人数,提供了具体的实现步骤和代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

类似前面的一道堆箱子

普适的解法是回溯,注意这类是求最值的回溯题。

另一种解法是LIS,先把其中一维排序,然后对剩下的一维进行LIS


package Sorting_Searching;

import java.util.ArrayList;
import java.util.Collections;


/**
 * A circus is designing a tower routine consisting of people standing atop one another’s shoulders. For practical and aesthetic reasons, each person must be both shorter and lighter than the person below him or her. Given the heights and weights of each person in the circus, write a method to compute the largest possible number of people in such a tower.

EXAMPLE:

Input (ht, wt): (65, 100) (70, 150) (56, 90) (75, 190) (60, 95) (68, 110)

Output: The longest tower is length 6 and includes from top to bottom: (56, 90) (60,95) (65,100) (68,110) (70,150) (75,190)

译文:

马戏团设计了这样一个节目:叠罗汉。一群人往上叠,每个人都踩在另一个人的肩膀上。 要求上面的人要比下面的人矮而且比下面的人轻。给出每个人的身高和体重, 写一个函数计算叠罗汉节目中最多可以叠多少人?

例子:

输入(身高 体重):(65, 100) (70, 150) (56, 90) (75, 190) (60, 95) (68, 110)

输出:最多可叠人数:6 (从上到下是:(56, 90) (60,95) (65,100) (68,110) (70,150) (75,190)) 
 *
 */
public class S11_7 {

	public static void main(String[] args) {
		ArrayList<HtWt> items = initialize();
		System.out.println(solve(items));
		ArrayList<HtWt> solution = getIncreasingSequence(items);
		printList(solution);
	}
	
	public static int solve(ArrayList<HtWt> items){
		boolean[] used = new boolean[items.size()];
		HtWt bottom = null;
		ArrayList<HtWt> ret = new ArrayList<HtWt>();
		int maxPeople = rec(items, used, bottom, ret);
		System.out.println(ret);
		return maxPeople-1;		// -1是因为第一个dummy element,我设置成null
	}
	
	public static int rec(ArrayList<HtWt> items, boolean[] used, HtWt cur, ArrayList<HtWt> curAL){
		
		boolean flag = false;			// 判断是否找到了一个选择
		int maxAbovePeople = 0;		// 基于当前的所有选择,找到最优子结构
		
		for(int i=0; i<items.size(); i++){
			if(!used[i]){
				used[i] = true;
				HtWt next = items.get(i);
				if(next.isBefore(cur)){
					flag = true;
					ArrayList<HtWt> nextAL = new ArrayList<HtWt>();		// 为子调用新建的AL
					int abovePeople = rec(items, used, next, nextAL);
					if(abovePeople > maxAbovePeople){
						curAL.clear();					// 必须先清除
						curAL.addAll(nextAL);		// 现在子序列中的就是能使得人数最多的选择
						maxAbovePeople = abovePeople;
					}
				}
				used[i] = false;
			}
		}
		
		
		if(flag == false){
			curAL.clear();
			curAL.add(cur);
			return 1;
		}
		
		curAL.add(cur);
		return maxAbovePeople+1;
	}
	
	public static ArrayList<HtWt> initialize() {
        ArrayList<HtWt> items = new ArrayList<HtWt>();
        
        HtWt item = new HtWt(70, 150);
        items.add(item);
        
        item = new HtWt(68, 110);
        items.add(item);

        item = new HtWt(56, 90);
        items.add(item);
        
        item = new HtWt(75, 190);
        items.add(item);
        
        item = new HtWt(60, 95);
        items.add(item);
        
        
        item = new HtWt(35, 65);
        items.add(item);
        
        item = new HtWt(40, 60);
        items.add(item);
        
        item = new HtWt(45, 63);
        items.add(item);
        
        return items;

	}
	
	public static void printList(ArrayList<HtWt> list) {
        for (HtWt item : list) {
                System.out.println(item.toString() + " ");
        }
	}

	static class HtWt implements Comparable {
		private int Ht;
		private int Wt;

		public HtWt(int h, int w) {
			Ht = h;
			Wt = w;
		}

		public int compareTo(Object s) {
			HtWt second = (HtWt) s;
			if (this.Ht != second.Ht) {
				return ((Integer) this.Ht).compareTo(second.Ht);
			} else {
				return ((Integer) this.Wt).compareTo(second.Wt);
			}
		}

		public String toString() {
			return "(" + Ht + ", " + Wt + ")";
		}

		/*
		 * Returns true if “this” should be lined up before “other”. Note that
		 * it’s possible that this.isBefore(other) and other.isBefore(this) are
		 * both false. This is different from the compareTo method, where if a <
		 * b then b > a.
		 */
		public boolean isBefore(HtWt other) {
			if(other == null){
				return true;
			}
			if (this.Ht < other.Ht && this.Wt < other.Wt) {
				return true;
			} else {
				return false;
			}
		}
	}
	
	//=========================== 另一种方法是用LIS来做
	private static ArrayList<HtWt> longestIncreasingSubsequence(ArrayList<HtWt> array) {
        ArrayList<HtWt>[] solutions = new ArrayList[array.size()];
        longestIncreasingSubsequence(array, solutions, 0);
        
        ArrayList<HtWt> best_sequence = null;
        for (int i = 0; i < array.size(); i++) {
        	best_sequence = seqWithMaxLength(best_sequence, solutions[i]);
        }
        
        return best_sequence;
	}
	
	private static void longestIncreasingSubsequence(ArrayList<HtWt> array, ArrayList<HtWt>[] solutions, int current_index) {
        if (current_index >= array.size() || current_index < 0) {
                return;
        }
        HtWt current_element = array.get(current_index);
        
        // Find longest sequence that we can append current_element to
        ArrayList<HtWt> best_sequence = null;
        for (int i = 0; i < current_index; i++) {
                if (array.get(i).isBefore(current_element)) { // If current_element is bigger than list tail
                        best_sequence = seqWithMaxLength(best_sequence, solutions[i]); // Set best_sequence to our new max
                }
        }
        
        // Append current_element
        ArrayList<HtWt> new_solution = new ArrayList<HtWt>();
        if (best_sequence != null) {
                new_solution.addAll(best_sequence);
        } 
        new_solution.add(current_element);
        
        // Add to list and recurse
        solutions[current_index] = new_solution;
        longestIncreasingSubsequence(array, solutions, current_index + 1);
	}
	
	// Returns longer sequence
    private static ArrayList<HtWt> seqWithMaxLength(ArrayList<HtWt> seq1, ArrayList<HtWt> seq2) {
            if (seq1 == null) {
                    return seq2;
            } else if (seq2 == null) {
                    return seq1;
            }
            return seq1.size() > seq2.size() ? seq1 : seq2;
    }
    
    public static ArrayList<HtWt> getIncreasingSequence(ArrayList<HtWt> items) {
        Collections.sort(items);
        return longestIncreasingSubsequence(items);
    }
}







<think>我们遇到了一个NameError:name'torch'isnotdefined错误。这个错误发生在config.py文件的第47行,当我们尝试检查CUDA是否可用时,引用了torch模块,但此时torch模块尚未导入或未定义。错误原因分析:在config.py中,我们尝试使用`torch.cuda.is_available()`,但是在使用之前,可能没有正确导入torch模块。因此,Python解释器不知道torch是什么。解决方案:我们需要确保在config.py文件中正确导入torch模块。在调用`torch.cuda.is_available()`之前,应该先导入torch。修改config.py文件:在config.py文件的顶部,添加导入torch的语句。但是,请注意,这个错误是在执行main.py时发生的,因为main.py导入了config.py。因此,我们需要在config.py中修正。让我们假设config.py的内容如下(包含错误的部分):在修改之前,config.py可能没有导入torch,所以我们应该在config.py的开头导入torch。修改后的config.py应该类似这样:```python#首先导入所需的模块importtorchimportos#然后定义其他配置#...其他配置...#现在可以安全地使用torch了DEVICE="cuda"iftorch.cuda.is_available()else"cpu"```这样,当main.py导入config.py时,torch模块就已经被导入了,不会出现NameError。另外,我们还需要确保已经正确安装了torch。如果没有安装,可以使用pip安装。总结:在config.py文件的开头添加`importtorch`。让我们修改config.py文件,然后重新运行main.py。</think> 这个错误的原因是 **`torch` 模块未被正确导入**,具体分析如下: --- ### 错误分析 ```python File "D:\commodity_sorting_system\code\config.py", line 47, in <module> DEVICE = "cuda" if torch.cuda.is_available() else "cpu" ^^^^^ NameError: name 'torch' is not defined ``` 错误发生在 `config.py` 文件的第47行,原因是: 1. 你在代码中使用了 `torch.cuda.is_available()` 2. 但在这之前没有导入 `torch` 模块 3. 因此 Python 解释器不知道 `torch` 是什么 --- ### 解决方案 在你的 `config.py` 文件开头添加 `import torch` 语句: ```python # 修改前的 config.py # ...其他配置... DEVICE = "cuda" if torch.cuda.is_available() else "cpu" # 错误位置 # 修改后的 config.py import torch # 添加这行导入语句 # ...其他配置... DEVICE = "cuda" if torch.cuda.is_available() else "cpu" # 现在可以正常工作 ``` ### 完整修复示例 ```python # D:\commodity_sorting_system\code\config.py import torch # 关键导入语句 import os # 数据集路径 DATA_DIR = "D:/commodity_sorting_system/data" TRAIN_IMAGES = os.path.join(DATA_DIR, r"train\images") TRAIN_LABELS = os.path.join(DATA_DIR, r"train\labels") VAL_IMAGES = os.path.join(DATA_DIR, r"val\images") VAL_LABELS = os.path.join(DATA_DIR, r"val\labels") # 模型配置 MODEL_PATH = "D:/commodity_sorting_system/yolov5s.pt" INPUT_SIZE = 640 # 设备配置(需要torch导入后使用) DEVICE = "cuda" if torch.cuda.is_available() else "cpu" ``` ### 为什么会发生这种错误? 1. **模块导入顺序问题**:Python 代码从上到下执行,使用模块前必须先导入 2. **常见遗漏**:特别是在配置文件中初始化全局变量时,容易忘记导入必要的模块 3. **最佳实践**:应该在文件的顶部集中导入所有需要的模块 --- ### 避免类似错误的建议 1. **使用 IDE 的提示功能**:像 PyCharm 会在未导入的模块下显示警告 2. **添加类型提示**: ```python import torch # 添加类型提示可避免某些错误 DEVICE: str = "cuda" if torch.cuda.is_available() else "cpu" ``` 3. **模块导入检查**: ```python try: import torch except ImportError: print("请安装PyTorch: pip install torch torchvision") exit(1) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值