算法导论15(动态规划)

15.1 钢条切割

//自顶向下递归实现
int cutRod(int *p,int n)
{
    if(n==0)return 0;
    int q=INT_MIN;
    for(int i=1;i<=n;++i)q=max(q,p[i]+cutRod(p,n-i));
    return q;
}

//带备忘的自顶向下法
int memoizedCutRodAux(int *p,int n,int *r)
{
    if(r[n]>=0)return r[n];
    int q;
    if(n==0)q=0;
    else
    {
        q=INT_MIN;
        for(int i=1;i<=n;++i)q=max(q,p[i]+memoizedCutRodAux(p,n-i,r));  
    }
    r[n]=q;
    return q;
}

int memoizedCutRod(int *p,int n)
{
    int *r=new int[n+1];
    for(int i=0;i<=n;++i)r[i]=INT_MIN;
    return memoizedCutRodAux(p,n,r);
}

//自底向上法
int bottomUpCutRod(int *p,int n)
{
    int *r=new int[n+1];
    r[0]=0;
    for(int j=1;j<=n;++j)
    {
        int q=INT_MIN;
        for(int i=1;i<=j;++j)q=max(q,p[i]+r[j-i]);
        r[j]=q;
    }
    return r[n];
}

//重构解
void extendedBottomUpCutRod(int *p,int n,int *r,int *s)
{
    r[0]=0;
    for(int j=1;j<=n;++j)
    {
        int q=INT_MIN;
        for(int i=1;i<=j;++j)
        {
            if(q<p[i]+r[j-i])
            {
                q=p[i]+r[j-i];
                s[j]=i;
            }
        }
        r[j]=q;
    }
}

void printCutRodSolution(int *p,int n)
{
    int *r=new int[n+1];
    int *s=new int[n+1];
    extendedBottomUpCutRod(p,n,r,s);
    while(n>0)
    {
        cout<<s[n]<<' ';
        n-=s[n];
    }
}

15.2 矩阵链乘法

//矩阵乘法
void matrixMultiply(vector<vector<int> > A,vector<vector<int> > B,vector<vector<int> > &C)
{
    if(A[0].size()!=B.size())return;
    for(int i=0;i<A.size();++i)
    {
        for(int j=0;j<B[0].size();++j)
        {
            C[i][j]=0;
            for(int k=0;k<A[0].size();++k)C[i][j]+=A[i][k]*B[k][j];
        }
    }
}

//矩阵链乘法
void matrixChainOrder(vector<int> p,vector<vector<int> > &m,vector<vector<int> > &s)
{
    int n=p.size()-1;
    for(int i=1;i<=n;++i)m[i][i]=0;
    for(int l=2;l<=n;++l)
    {
        for(int i=1;i<=n-l+1;++i)
        {
            int j=i+l-1;
            m[i][j]=INT_MAX;
            for(int k=i;k<=j-1;++k)
            {
                int q=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
                if(q<m[i][j])
                {
                    m[i][j]=q;
                    s[i][j]=k;
                }
            }
        }
    }
}

void printOptimalParens(vector<vector<int> > s,int i,int j)
{
    if(i==j)cout<<"A"<<i;
    else
    {
        cout<<'(';
        printOptimalParens(s,i,s[i][j]);
        printOptimalParens(s,s[i][j]+1,j);
        cout<<')';
    }
}

15.3 动态规划原理

//递归
int recursiveMatrixChain(vector<int> p,int i,int j,vector<vector<int> > &m)
{
    if(i==j)return 0;
    m[i][j]=INT_MAX;
    for(int k=i;k<=j-1;++k)
    {
        int q=recursiveMatrixChain(p,i,k,m)+recursiveMatrixChain(p,k+1,j,m)+p[i-1]*p[k]*p[j];
        if(q<m[i][j])m[i][j]=q;
    }
    return m[i][j];
}

//备忘
int lookupChain(vector<vector<int> > m,vector<int> p,int i,int j)
{
    if(m[i][j]<INT_MAX)return m[i][j];
    if(i==j)m[i][j]=0;
    else
    {
        for(int k=i;k<=j-1;++k)
        {
            int q=lookupChain(m,p,i,k)+lookupChain(m,p,k+1,j)+p[i-1]*p[k]*p[j];
            if(q<m[i][j])m[i][j]=q;
        }
    }
    return m[i][j];
}

int memoizedMatrixChain(vector<int> p)
{
    int n=p.size()-1;
    vector<vector<int> > m(n+1,vector<int>(n+1,INT_MAX));
    return lookupChain(m,p,1,n);
}

15.4 最长公共子序列

void LCSLength(vector<char> X,vector<char> Y,vector<vector<int> > &b,vector<vector<int> > &c)
{
    int m=X.size();
    int n=Y.size();
    for(int i=1;i<=m;++i)c[i][0]=0;
    for(int j=0;j<=n;++j)c[0][j]=0;
    for(int i=1;i<=m;++i)
    {
        for(int j=1;j<=n;++j)
        {
            if(X[i]==Y[j])
            {
                c[i][j]=c[i-1][j-1]+1;
                b[i][j]=1;
            }
            else if(c[i-1][j]>=c[i][j-1])
            {
                c[i][j]=c[i-1][j];
                b[i][j]=2;
            }
            else
            {
                c[i][j]=c[i][j-1];
                b[i][j]=3;
            }
        }
    }
}

void printLCS(vector<vector<int> > b,vector<char> X,int i,int j)
{
    if(i==0||j==0)return;
    if(b[i][j]==1)
    {
        printLCS(b,X,i-1,j-1);
        cout<<X[i]<<' ';
    }
    else if(b[i][j]==2)printLCS(b,X,i-1,j);
    else printLCS(b,X,i,j-1);
}

15.5 最优二叉搜索树

//p[1..n]
//q[0..n]
//e[1..n+1,0..n]
//w[1..n+1,0..n]
//root[1..n,1..n]
//时间复杂度为O(n^3)
void optimalBST(vector<int> p,vector<int> q,int n,vector<vector<int> > &e,vector<vector<int> > &w,vector<vector<int> > &root)
{
    for(int i=1;i<=n+1;++i)e[i][i-1]=w[i][i-1]=q[i-1];
    for(int l=1;l<=n;++l)
    {
        for(int i=1;i<=n-l+1;++i)
        {
            int j=i+l-1;
            e[i][j]=INT_MAX;
            w[i][j]=w[i][j-1]+p[j]+q[j];
            for(int r=i;r<=j;++r)
            {
                int t=e[i][r-1]+e[r+1][j]+w[i][j];
                if(t<e[i][j])
                {
                    e[i][j]=t;
                    root[i][j]=r;
                }
            }
        }

    }
}

//改进,时间复杂度为O(n^2)。
void optimalBST(vector<int> p,vector<int> q,int n,vector<vector<int> > &e,vector<vector<int> > &w,vector<vector<int> > &root)
{
    for(int i=1;i<=n+1;++i)e[i][i-1]=w[i][i-1]=q[i-1];
    for(int l=1;l<=n;++l)
    {
        for(int i=1;i<=n-l+1;++i)
        {
            int j=i+l-1;
            e[i][j]=INT_MAX;
            w[i][j]=w[i][j-1]+p[j]+q[j];    
            //root[i][j-1]<=root[i][j]<=root[i+1][j]
            if(i==j)
            {
                int t=e[i][r-1]+e[r+1][j]+w[i][j];
                if(t<e[i][j])
                {
                    e[i][j]=t;
                    root[i][j]=i;
                }
            }
            else
            {
                for(int r=root[i][j-1];r<=root[i+1][j];++r)
                {
                    int t=e[i][r-1]+e[r+1][j]+w[i][j];
                    if(t<e[i][j])
                    {
                        e[i][j]=t;
                        root[i][j]=r;
                    }
                }
            }
        }
    }
}

思考题
15-1

const int N=100;

struct ENode
{
    int val,w;
    ENode *next;
};

struct VNode
{
    ENode *next;
};

struct Graph    
{    
    VNode Adj[N];    
    int VNum,ENum;    
};    

void longestPathAux(Graph G,int u,int t,int *dist,int *next)
{
    if(u==t)dist[u]=0;
    else if(next[u]==0)
    {
        for(ENode *p=G.Adj[u].next;p;p=p->next)
        {
            int v=p->val,w=p->w;
            longestPathAux(G,v,t,dist,next);
            if(w+dist[v]>dist[u])
            {
                dist[u]=w+dist[v];
                next[u]=v;
            }
        }
    }
}

void printPath(int s,int t,int *next)
{
    int u=s;
    cout<<u;
    while(u!=t)
    {
        cout<<"->"<<next[u];
        u=next[u];
    }
}

void longestPathMain(Graph G,int s,int t)
{
    int n=G.VNum;
    int *dist=new int[n+1],*next=new int[n+1];
    for(int i=1;i<=n;++i)
    {
        dist[i]=INT_MIN;
        next[i]=-1;
    }
    longestPathAux(G,s,t,dist,next);
    if(dist[s]==INT_MIN)cout<<"No path exits"<<endl;
    else
    {
        cout<<"The weight of the longest path is "<<dist[s]<<endl;
        printPath(s,t,next);
    }
    delete [] dist,next;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值