UVA - 10131 Is Bigger Smarter?(dp+最大升序子序列)

本文深入探讨了如何通过排序算法找到大象群体中,按照智商从大到小、重量从小到大排列的最长子序列,并详细展示了实现这一目标的具体步骤及代码解析。
题目分析:
找出重量从小到大、智商从大到小排列的最长子序列。
并输出这些序列的编号。


解题思路:
1、对大象按IQ从大到小排序。
2、用最大升序子序列的方法,按照重量从小到大,求出最多的大象,用路径path[i]记下j(i之前那头大象)。

3、输出最长序列的长度,并递归输出路径。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
struct Node {
	int w,s,id;
}e[N];
int n;
int dp[N],ans[N],path[N];

bool cmp(Node a,Node b) {
	return a.s > b.s;
}
void print_path(int cur) {
	if(dp[cur] == 1) {
		printf("%d\n",e[cur].id);
		return;
	}
	print_path(path[cur]);
	printf("%d\n",e[cur].id);
}
int main() {
	n = 0;
	while(scanf("%d%d",&e[n].w,&e[n].s) != EOF) {
		e[n].id = n+1;
		n++;
	}
	sort(e,e+n,cmp);
	for(int i = 0; i < n; i++) {
		dp[i] = 1;
		path[i] = i;
	}

	int maxx = 0 , pos = 0;
	for(int i = 1; i < n; i++) {
		int maxd = 0;
		for(int j = 0; j < i; j++) {
			if(e[i].w > e[j].w && dp[j] > maxd) {
				maxd = dp[j];
				path[i] = j; //i之前的那个大象
			}
		}
		dp[i] = maxd + 1;
		if(maxx < dp[i]) {
			maxx = dp[i];
			pos = i;
		}
	}
	printf("%d\n",maxx);
	print_path(pos);
	return 0;
}


>> L(1) = Link('d', 0, 'a', 0.5, 'alpha', 0, 'standard'); >> L(2) = Link('d', 0, 'a', 0.8, 'alpha', pi/2, 'standard'); >> L(3) = Link('d', 0.2, 'a', 0, 'alpha', -pi/2,'standard'); >> robot = SerialLink(L, 'name', '3DOF-Arm'); >> robot.teach; 索引超过数组元素的数量。索引不能超过 4。 出错 SerialLink/plot>create_robot (第 468 行) d = norm( d(4:6)-d(1:3) ) / 72; ^^^^^^ 出错 SerialLink/plot (第 251 行) handle = create_robot(robot, opt); ^^^^^^^^^^^^^^^^^^^^^^^^ 出错 SerialLink/teach (第 103 行) robot.plot(q, args{:}); ^^^^^^^^^^^^^^^^^^^^^^ >> disp(['机械臂自由度: ', num2str(robot.n)]); 机械臂自由度: 3 >> robot.display robot = 3DOF-Arm:: 3 axis, RRR, stdDH, slowRNE +---+-----------+-----------+-----------+-----------+-----------+ | j | theta | d | a | alpha | offset | +---+-----------+-----------+-----------+-----------+-----------+ | 1| q1| 0| 0.5| 0| 0| | 2| q2| 0| 0.8| 1.5708| 0| | 3| q3| 0.2| 0| -1.5708| 0| +---+-----------+-----------+-----------+-----------+-----------+ >> q_test = [pi/6, -pi/4, pi/3]; >> figure; >> robot.plot(q_test, 'workspace', [-2 2 -2 2 -1 3], 'view', '3d'); 警告: floor tiles too small, making them 2.000000 x bigger - change the size or disable them > 位置:RTBPlot.create_tiled_floor (第 619 行) 位置: RTBPlot.create_floor (第 575 行) 位置: SerialLink/plot (第 250 行) 索引超过数组元素的数量。索引不能超过 4。 出错 SerialLink/plot>create_robot (第 468 行) d = norm( d(4:6)-d(1:3) ) / 72; ^^^^^^ 出错 SerialLink/plot (第 251 行) handle = create_robot(robot, opt); ^^^^^^^^^^^^^^^^^^^^^^^^ >> title('标准DH三自由度机械臂'); >>
03-29
<think>嗯,用户遇到了在使用MATLAB Robotics Toolbox建立三自由度机械臂模型时出现的索引超出数组元素数量的错误。让我仔细看看这个问题。用户提供的代码在定义DH参数时似乎正确,但在调用robot.teach和robot.plot时出现了错误。错误信息指向SerialLink/plot中的第468行,提示索引超过数组元素的数量,特别是d(4:6)和d(1:3)的部分。这说明在创建机器人模型时,可能某个参数设置不正确,导致在计算某个部分时数组长度不够。 首先,我需要回忆一下标准DH参数的定义以及Robotics Toolbox中Link对象的参数顺序。用户定义每个Link时使用的是'd', 'a', 'alpha', 'theta'的顺序,但根据Robotics Toolbox的文档,Link函数的参数顺序应该是theta, d, a, alpha。不过,当使用'standard'参数时,是否允许以不同的顺序输入呢?可能用户在这里混淆了参数的顺序,导致Toolbox内部解析时出现错误。 接下来,用户提供的代码中,L(1)的d设为0,a为0.5,alpha为0,而L(2)的d为0,a为0.8,alpha为pi/2,L(3)的d为0.2,a为0,alpha为-pi/2。根据标准DH参数的定义,每个连杆的参数应该是d(沿前一个z轴的平移)、a(沿当前x轴的平移)、alpha(绕当前x轴的旋转),而theta是绕前一个z轴的旋转。在MATLAB中,当创建Link对象时,参数顺序是否正确? 查看Robotics Toolbox的文档,Link对象的构造函数参数顺序是:Link([theta d a alpha], 'standard')。所以,用户在代码中使用的是Link('d', 0, 'a', 0.5, 'alpha', 0, 'standard'),但实际上应该按照theta, d, a, alpha的顺序来传递参数。用户可能错误地使用了关键字参数,而Robotics Toolbox的Link函数可能并不支持这种写法,导致参数被错误解析,从而在后续的plot函数中引发错误。 例如,用户定义L(1)的代码是: L(1) = Link('d', 0, 'a', 0.5, 'alpha', 0, 'standard'); 但正确的应该是: L(1) = Link([0 0 0.5 0], 'standard'); 或者使用键值对的方式,但需要确认Link函数是否支持。可能用户误用了键值对参数,而实际上应该按顺序传递参数。例如,正确的参数顺序是theta, d, a, alpha,而用户可能错误地将d作为第二个参数,而忽略了theta的位置。在标准DH中,theta是关节变量,如果关节是旋转型的,则theta会被视为变量q。因此,在定义Link时,如果theta是变量,应将其设置为0,并在offset中指定,或者由关节变量处理。可能用户没有正确设置theta参数,导致参数顺序错乱。 例如,正确的Link定义应该是: L(1) = Link('d', 0, 'a', 0.5, 'alpha', 0, 'standard'); 但根据文档,Link的构造函数可能不支持键值对参数,而是需要按顺序传递参数。例如: L(1) = Link('standard', 'd', 0, 'a', 0.5, 'alpha', 0); 或者,更可能的正确方式是使用参数顺序:[theta d a alpha],所以用户应该使用: L(1) = Link([0 0 0.5 0], 'standard'); 这样,四个参数按顺序排列。用户可能错误地使用了键值对参数,导致参数被错误解析,进而导致在创建机器人模型时,某些参数未被正确设置,从而在绘图时出现数组索引错误。 例如,当用户使用Link('d', 0, 'a', 0.5, 'alpha', 0, 'standard')时,可能Toolbox的Link函数将这些参数误解,导致实际存储的参数顺序错误,进而使得在绘图时计算某些变换矩阵时,数组维度不匹配,从而引发索引超出范围的错误。 此外,用户在定义第三个连杆时,d为0.2,这可能是一个移动关节,但根据错误信息,问题可能出现在这里的参数设置。需要确认第三个连杆的DH参数是否正确,尤其是alpha为-pi/2的情况下,是否与其他连杆的参数组合导致坐标系变换出现问题。 另一个可能的原因是Robotics Toolbox版本问题。用户使用的版本可能与代码不兼容,导致某些函数处理方式不同。例如,旧版本可能对参数顺序或键值对的输入方式支持不同,从而引发错误。建议用户检查Toolbox的版本,并查看对应版本的文档。 另外,用户遇到的警告信息“floor tiles too small”可能与工作空间设置有关,但主要错误还是索引超出数组元素的数量。这说明问题出在机器人模型的参数定义上,而非仅仅是绘图设置。 总结可能的原因: 1. Link参数顺序错误,未按theta, d, a, alpha的顺序传递,导致参数解析错误。 2. 使用键值对参数的方式不正确,Toolbox的Link函数不支持或解析错误。 3. 第三个连杆的DH参数设置导致变换矩阵计算异常。 4. Toolbox版本兼容性问题。 解决方案建议: 1. 检查Link的创建方式,确保参数按正确的顺序传递。 2. 使用正确的参数顺序定义每个Link,例如:Link([theta d a alpha], 'standard')。 3. 确认所有参数的单位和类型正确,如旋转关节的theta应设置为0,并在offset中指定初始值(如果需要)。 4. 更新或检查Robotics Toolbox的版本,确保与代码兼容。 例如,将Link的定义改为按顺序传递参数: L(1) = Link([0 0 0.5 0], 'standard'); % theta=0, d=0, a=0.5, alpha=0 L(2) = Link([0 0 0.8 pi/2], 'standard'); L(3) = Link([0 0.2 0 -pi/2], 'standard'); 这样,每个Link的参数顺序正确,避免解析错误。 另外,用户可能忘记将关节类型设置为旋转或移动,但标准DH参数中,旋转关节的d是固定的,theta是变量;移动关节的theta是固定的,d是变量。如果用户定义的关节都是旋转型的,则theta应为变量,即Link的sigma参数默认为0(旋转关节)。在用户的代码中,所有关节都是旋转型的,所以参数设置正确。因此,问题更可能出在参数顺序的输入方式上。 最后,用户在错误信息中看到索引超过4,可能是因为在某个变换矩阵中,期望得到至少6个元素,但实际得到的不够。例如,在计算某个向量时,期望的是位置向量有3个元素,但可能由于参数错误导致得到的向量长度不足,从而在访问4:6时越界。这进一步表明DH参数设置错误,导致变换矩阵生成异常。 综上所述,用户应调整Link的定义方式,使用正确的参数顺序,并确保所有参数正确传递,以解决索引超出范围的错误。</think>以下是针对索引越界错误的详细分析和解决方案: --- ### **错误原因分析** 通过错误信息`索引超过数组元素的数量。索引不能超过4`可以定位到**连杆参数定义顺序错误**。Robotics Toolbox的`Link`构造函数需严格按照`[theta d a alpha]`顺序传递参数,而代码中使用键值对输入会导致参数解析异常,最终引发运动学计算时的数组越界。 --- ### **修正代码** ```matlab %% =================== 标准DH参数修正定义 =================== % 参数顺序强制使用[theta, d, a, alpha] % 语法:Link([theta, d, a, alpha], 'standard') % 关节1:基座到第一个旋转关节 L(1) = Link([0, 0, 0.5, 0], 'standard'); % theta为关节变量q1 % 关节2:第一到第二旋转关节 L(2) = Link([0, 0, 0.8, pi/2], 'standard'); % alpha=pi/2 % 关节3:第二到第三旋转关节 L(3) = Link([0, 0.2, 0, -pi/2], 'standard'); % d=0.2 %% =================== 创建修正模型 =================== robot = SerialLink(L, 'name', '3DOF-Arm'); robot.teach; % 此时应正常显示交互界面 ``` --- ### **关键修改说明** 1. **参数顺序标准化** - **错误写法**:`Link('d', 0, 'a', 0.5, 'alpha', 0, 'standard')` - **正确写法**:`Link([theta, d, a, alpha], 'standard')` - 原因:`Link`构造函数默认按顺序解析参数,键值对输入会破坏参数映射关系 2. **关节变量定义明确化** - 所有`theta`初始设为0,表示关节角度初始为0(实际运动时由`q`值动态计算) 3. **避错验证增强** ```matlab % 验证参数是否被正确解析 disp('关节1参数:'); disp([L(1).theta L(1).d L(1).a L(1).alpha]); % 应输出[0 0 0.5 0] ``` --- ### **修正后效果验证** 1. **运行`robot.teach`** - 应正常弹出交互界面,拖动滑块观察各关节运动 2. **执行正运动学计算** ```matlab q_test = [pi/6, -pi/4, pi/3]; T = robot.fkine(q_test); disp('末端位姿矩阵:'); disp(T.T); % 应输出有效的4x4变换矩阵 ``` 3. **检查绘图功能** ```matlab robot.plot(q_test, 'workspace', [-2 2 -2 2 -1 3], 'view', '3d', 'nobase'); % 禁用地面网格避免警告 ``` --- ### **常见问题补充** 1. **关于地面网格警告** 添加`'nobase'`选项可屏蔽`floor tiles too small`警告: ```matlab robot.plot(q_test, 'nobase', 'view', '3d'); ``` 2. **参数单位一致性检查** 通过`robot.display`输出确认单位: ```matlab robot.display % 检查a/d单位为米,alpha为弧度 ``` 3. **版本兼容性建议** - 确认使用Robotics Toolbox **v10+**(推荐Peter Corke维护版本) - 更新工具箱命令:`rtbupdate` --- **修正后的代码应能完全消除索引越界错误,并正常进行运动学仿真**。如果问题仍存在,请提供MATLAB版本和Robotics Toolbox版本信息以便进一步诊断。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值