求最长子序列问题(采用树的解法)

[复制链接]
查看11 | 回复8 | 2021-1-27 07:11:48 | 显示全部楼层 |阅读模式
原题如下:
有一无序数列:x1,x2...xn。用从该序列中删除若干数字的方法,使剩下的长度为m的序列成为单调递减序列。要求构造算法求得m值为最大的解。
例如:序列486521321
删除3个数(4)865(2)(1)321
结果:865321(m=6)
要求:用二叉数遍历的方法编程求出长度m为最大的序列,算法要点如下:1)原序列的每一元素均有保留和删除两种可能,可抽象为二叉树结构。2)二叉树中符合序关系要求的,具有最多保留节点的树枝即为解。3)二叉树结构是逻辑描述,实现时也可不使用实际树结构,保证状态遍历的完备性即可。4)要求输出该最长单调递减序列(如有等长的最长单调序列,则均输出)
这题想了好长时间了也没做出来,郁闷了。
这里人气高,借此地解惑,希望高手们不吝赐教啊。先谢了!
分 -->
回复

使用道具 举报

千问 | 2021-1-27 07:11:48 | 显示全部楼层
不用树就简单了。
回复

使用道具 举报

千问 | 2021-1-27 07:11:48 | 显示全部楼层
同样的问题,
http://community.csdn.net/Expert/TopicView3.asp?id=5308636
回复

使用道具 举报

千问 | 2021-1-27 07:11:48 | 显示全部楼层
//没有考虑用二叉树,用递归很简单。
const
barr:array[0..9]ofByte=
(3,9,7,6,3,2,4,3,2,0
);
functionGetMaxSerial(LessThan:integer;PArr:PByte;varOutStr:string):integer;
var
L1,L2:integer;
v:integer;
tmp1:string;
tmp2:string;
begin
v:=PArr^;
Inc(PArr);
ifv=0then//结束
begin
Result:=0;
OutStr:='';
end
elseifv>=LessThanthen//扔掉当前数
Result:=GetMaxSerial(LessThan,PArr,OutStr)
else
begin
L1:=GetMaxSerial(LessThan,PArr,tmp1);//扔掉当前数
L2:=1+GetMaxSerial(v,PArr,tmp2);//保留当前数
ifL1>=L2then
begin
Result:=L1;
OutStr:=tmp1;
end
else
begin
Result:=L2;
OutStr:=IntToStr(v)+','+tmp2;
end;
end;
end;
var
L:integer;
S:string;
procedureTForm1.Button1Click(Sender:TObject);
begin
L:=GetMaxSerial(256,@barr,S);
end;
回复

使用道具 举报

千问 | 2021-1-27 07:11:48 | 显示全部楼层
虽然不是用树实现的还是谢谢强哥
希望有树的算法啊,再次请教,还有50分!
回复

使用道具 举报

千问 | 2021-1-27 07:11:48 | 显示全部楼层
http://community.csdn.net/Expert/TopicView.asp?id=5305770
回复

使用道具 举报

千问 | 2021-1-27 07:11:48 | 显示全部楼层
这应该是个NP-复杂性问题,不好找最优解吧?
回复

使用道具 举报

千问 | 2021-1-27 07:11:48 | 显示全部楼层
http://community.csdn.net/Expert/TopicView.asp?id=5305770
对,我也想到了这个算法。
就是scv120的算法。
我定义的插入元素的方法是:
curnode:当前在树中定位到的节点
inservalue:要插入的值
isleft:当前在树中定位到的节点是其父节点的左节点,还是右节点
issmall:当前在树中定位到的节点比其父节点大或小。
setItem(curnode,insertvalue,isleft,issmall)
{
if(curnode==NULL)
{
if(isleft)curnode=getnode(insertvalue);
elseif(notissmall)curnode=getnode(insertvalue);
}
else{
if(*curnode
#include
#include
#definetrue1
#definefalse0
structTreeNode{
intvalue;
structTreeNode*leftNode;
structTreeNode*rightNode;
intpathFlag;/*0:在得到最终线路时应往左下去1:在得到最终线路时应往右下去-1:终点*/
};
/*将一个值变为一个节点传出*/
structTreeNode*getNode(intvalue){
structTreeNode*treenode;
treenode=(structTreeNode*)malloc(sizeof(structTreeNode));
treenode->value=value;
treenode->leftNode=NULL;
treenode->rightNode=NULL;
returntreenode;
}
/*得到输入值*/
intgetinputValue(){
charstr[20];
printf("input:(结束:-1)\n");
gets(str);/*是获得字符串*/
returnatoi(str);/*strtoint*/
}
/*插入数据
curnode:当前在树中定位到的节点
inservalue:要插入的值
isleft:当前在树中定位到的节点是其父节点的左节点,还是右节点
issmall:当前在树中定位到的节点比其父节点大或小。
*/
voidinsertItem(structTreeNode**curnode,intinsertvalue,intisleft,intissmall)
{
if(*curnode==NULL)
{
if(isleft==true)*curnode=getNode(insertvalue);
elseif(issmall==false)*curnode=getNode(insertvalue);
}
else{
if(insertvaluevalue){
insertItem(&((*curnode)->leftNode),insertvalue,true,true);
insertItem(&((*curnode)->rightNode),insertvalue,false,true);
}
else{
insertItem(&((*curnode)->rightNode),insertvalue,false,false);
}
}
}
/*得到最终路线,返回路线的长度*/
intgetPath(structTreeNode*curnode){
intleftvalue;
intrightvalue;
intret;
if(curnode==NULL){
return-1;
}
printf("(");
leftvalue=getPath(curnode->leftNode);
printf("%d",curnode->value);
rightvalue=getPath(curnode->rightNode);
printf(")");
if(rightvalue==-1&&leftvalue==-1){
curnode->pathFlag=-1;
ret=1;
}
else{
if(leftvalue>=rightvalue){
curnode->pathFlag=0;
ret=leftvalue+1;
}
else{
curnode->pathFlag=1;
ret=rightvalue;
}
}

returnret;
}
/*将树中的最终链打印出来*/
putvalue(structTreeNode*curnode){
if(curnode->pathFlag==0){
printf("%d",curnode->value);
putvalue(curnode->leftNode);
}
elseif(curnode->pathFlag==1){
putvalue(curnode->rightNode);
}
else{
printf("%d",curnode->value);
}
}
int
main(){
intvalue;
structTreeNode*root=NULL;
while((value=getinputValue())!=-1){/*输入-1则退出输入*/
insertItem(&root,value,true,true);
}
printf("\n子串的长度:%d\n",getPath(root));
if(root!=NULL)
{
printf("得到的序列:");
putvalue(root);
}
printf("\n");
return0;
}

回复

使用道具 举报

千问 | 2021-1-27 07:11:48 | 显示全部楼层
if(insertvaluevalue){
insertItem(&((*curnode)->leftNode),insertvalue,true,true);
insertItem(&((*curnode)->rightNode),insertvalue,false,true);
}

这个insertItem(&((*curnode)->rightNode),insertvalue,false,true);
总觉得有点多余
好像不必要把,能解释下吗?谢谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行