回文子序列与欧几里德旅行商

回文子序列

最长回文子序列是正序与逆序相同的非空字符串。例如,所有长度为1的字符串,civic,racecar,aibobphobia都是回文。设计算法,求给定输入字符串的最长回文子序列。例如,给定输入character,算法应该返回carac。算法的运行时间是怎么样的?

算法设计与分析:

注意这里是回文子序列,而不是回文子串。求子串和子序列有一些不同,这里的方法用于求子序列。
字串的意义是:aaabbb,需要连续的字符相同。

而子序列,是字母按照一定的排列顺序,保持回文的一致性就可以。

实现过程:将原字符串反转,然后用LCS_length(),Print_LCS()计算出最长公共子序列即可。

palidrome_longest.h

#include 
#include 
#include 

using namespace std;

#define N 9                 //输入您要判断的字符串的字符数
wchar_t b[N+1][N+1]={'S'};  //表示起点start
int c[N+1][N+1]={0};
wchar_t northwest=L'\\', up=L'|', leftway=L'-';
void LCS_length(char *x,char *y)
{
    for(int i1=0;i1=c[i+1][j])
                //c[i-1][j-1] 过渡到 c[i][j],需要将c[i-1][j]和c[i][j-1]比较大小
                //取较大的那一个值
                {
                    c[i+1][j+1]=c[i][j+1];
                    b[i+1][j+1]=up;  //Up往上
                }
                else
                {
                    c[i+1][j+1]=c[i+1][j];
                    b[i+1][j+1]=leftway;  //Left往左
                }
            }
        }
    }
}
void Print_lcs(char *x,int i,int j)
{
    if(i==0||j==0)
      return;
    if(b[i][j]==northwest)
    {
        Print_lcs(x,i-1,j-1);
        cout<

palidrome_longest.cpp

#include "palidrome_longest.h"

int main()
{
    char x[N+1]={0};
    char y[N+1]={0};
    char c;
    cout<<"get the string you need to judge: "<>c;
        y[i]=x[i]=c;
    }
    x[i]='\0';y[i]='\0';
    cout<

欧几里德旅行商问题

算法分析图

Eucilid_travel.h

#include 
#include 

using namespace std;

#define N 7  //确定有几个点?

struct travelnode
{
    double x;
    double y;
}T[N];

//计算两个点之间的直线距离
double distance(travelnode T[],int i,int j)  //T[]的下标,第几个数?1,2....N
{
    return sqrt((T[i].x-T[j].x)*(T[i].x-T[j].x)+(T[i].y-T[j].y)*(T[i].y-T[j].y));
}

double Bitonic_Eucilid(travelnode T[])
{
    double b[N+1][N+1]={0};

    //初始化b[1][4],注意初始下标从1开始,1,2.....N
    b[1][5]=distance(T,1,2);
    for(int j=3;j<=N;j++)
    {
        for(int i=1;ij-1)+(start->i)+length(j-1,j))
            //即b[i][j]=b[i][j-1]+distance(T,j-1,j) 这里distance(T,j-1,j)封闭了路径
        }

        //注意:这里递归求解所得到的路径,b[i][j]不一定就是最短的欧几里德旅行商
        //必须用min()维护旅行商信息
        //用min()维护每一条线段[j-1,j],保证从length(start->j-1)+length(start->k)+length(k,j)均是最小的

        //如图所示:对每一个线段[j-1,j]的两端进行维护,保证最短的Eucilid巡回,即维护b[j-1][j]
        //在维护的过程中b[j-1][j]=min(b[k][j-1]+distance(k,j)),封闭了[k,j]就获取了最佳路径
        //因为j是在最远端,1<=k<=j-1i+start->j的路径,但是巡路并不是封闭的
        //最后确定b[j-1][j],即确定线段[j-1,j],完成巡路封闭。
        //这里b[j-1][j]要保证遍历1<=kj-1)+(start->k)+length(k,j)
            //由于1<=k

Eucilid_travel.cpp

#include "Eucilid_travel.h"

int main()
{
    travelnode T[N+1]={0};
    cout<<"Input the numbers in order : "<>T[i].x>>T[i].y;
    }
    cout<

旅行商的重构解

Print函数的递归分析

特别注意:

if(s

或者是:

if(s>k)
    print_eucilid(solution,val,k);

如图中绿色线条所示:递归的过程,无论是s->val还是val->s,均是由较大坐标的点转向较小坐标的点。
二者的区别在于:s

而s>k的时候,则先递归输出顺时针方向其余的点,再输出val=solution[k] [s]的值。

注意这里是solution[k] [s]

当然递归和val的输出的先后顺序,取决于你是按顺时针还是逆时针输出。

Eucilid_travel_constitute.h

#include 
#include 

using namespace std;

#define N 7  //确定有几个点?

struct travelnode
{
    double x;
    double y;
}T[N];

//计算两个点之间的直线距离
double distance(travelnode T[],int i,int j)  //T[]的下标,第几个数?1,2....N
{
    return sqrt((T[i].x-T[j].x)*(T[i].x-T[j].x)+(T[i].y-T[j].y)*(T[i].y-T[j].y));
}


double Bitonic_Eucilid(travelnode T[],int solution[][N+1])
{
    double b[N+1][N+1]={0};

    //初始化b[1][8],注意初始下标从1开始,1,2.....N
    b[1][9]=distance(T,1,2);
    for(int j=3;j<=N;j++)
    {
        for(int i=1;ij-1)+(start->i)+length(j-1,j))
            //即b[i][j]=b[i][j-1]+distance(T,j-1,j) 这里distance(T,j-1,j)封闭了路径
            solution[i][j]=j-1;
        }

        //注意:这里递归求解所得到的路径,b[i][j]不一定就是最短的欧几里德旅行商
        //必须用min()维护旅行商信息
        //用min()维护每一条线段[j-1,j],保证从length(start->j-1)+length(start->k)+length(k,j)均是最小的

        //如图所示:对每一个线段[j-1,j]的两端进行维护,保证最短的Eucilid巡回,即维护b[j-1][j]
        //在维护的过程中b[j-1][j]=min(b[k][j-1]+distance(k,j)),封闭了[k,j]就获取了最佳路径
        //因为j是在最远端,1<=k<=j-1i+start->j的路径,但是巡路并不是封闭的
        //最后确定b[j-1][j],即确定线段[j-1,j],完成巡路封闭。
        //这里b[j-1][j]要保证遍历1<=kj-1)+(start->k)+length(k,j)
            //由于1<=k1)
            print_eucilid(solution,s,val);
    }
    else  
    {
        int val=solution[k][s];
        if(val>1)
        {
            print_eucilid(solution,val,k);
        }
        cout<

Eucilid_travel_constitute.cpp

#include "Eucilid_travel_constitute.h"

int main()
{
    travelnode T[N+1]={0};
    int solution[N+1][N+1]={0};

    cout<<"Input the numbers in order : "<>T[i].x>>T[i].y;
    }
    cout<

算法运行结果

][10]

你可能感兴趣的:(动态规划,算法导论)