12345,上山打老虎。

别说谁变了你拦得住时间么 提交于 2019-12-26 00:35:02

一、 矩阵连乘的动态规划算法和程序

算法:

程序:

///测试数据30 35 35 15 15 5 5 10 10 20 20 25
#include<bits/stdc++.h>
using namespace std;
#define MAXN 911
#define Max 99999999
struct MatrixDimension
{
    int n,m;           ///表示矩阵是n*m维的
} Di[MAXN];
void MatrixChain(MatrixDimension MD[], int **s, int **bestnum, int n);
void print(int **s, int l, int r);
int main()
{
    int n, i;
    cout<<"输入矩阵个数n = ";
    cin>>n;
    cout<<"输入"<<n<<"个矩阵的维数:"<<endl;
    for(i = 0; i < n; i++)
        cin>>Di[i].n>>Di[i].m;
    int **s = new int*[n];
    for(int i = 0; i < n; i++)
        s[i] = new int[n];
    int **bm = new int*[n];
    for(int i = 0; i < n; i++)
        bm[i] = new int[n];
    MatrixChain(Di, s, bm, n);
    cout<<"输出矩阵bm和s:"<<endl;
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < n; j++)
        {
            if(i <= j)
                cout<<left<<fixed<<setw(7)<<bm[i][j];
            else
                cout<<left<<fixed<<setw(7)<<s[j][i];
        }
        cout<<endl;
    }
    print(s,0,n-1);
}
void MatrixChain(MatrixDimension MD[], int **s, int **bestnum, int n)
{
    for(int i = 0; i < n; i++)
        bestnum[i][i] = 0;
    for(int r = 1; r < n; r++)    ///r代表第r条对角线
    {
        for(int i = 0; i < n - r; i++)
        {
            int k = i + r;
            bestnum[i][k] = Max;
            for(int j = i; j < k; j++) ///接下来求从第i个矩阵到第k个矩阵的最优值及最优解
            {
                int temp = bestnum[i][j] + bestnum[j+1][k] + MD[i].n * MD[j].m * MD[k].m;
                if(bestnum[i][k] >= temp)
                {
                    bestnum[i][k] = temp;
                    s[i][k] = j;
                }
            }
        }
    }
}
void print(int **s, int l, int r)
{
    if(l >= r)
    {
        cout<<"A"<<l;
        return ;
    }
    int temp = s[l][r];
    cout<<"(";
    print(s,l,temp);
    print(s,temp+1,r);
    cout<<")";
}




二、最长公共子序列的动态规划算法和程序

算法:

程序:

///测试数据
///A B C B D A B
///B D C A B A
#include<bits/stdc++.h>
using namespace std;
void LCSlength(int n, int m, char *s1, char *s2, int **c, int **b);
void print(char *s1, char *s2, int nr, int mr, int **c);
int main()
{
    int n, m;
    cout<<"输入序列1的长度n = ";
    cin>>n;
    cout<<"输入序列2的长度m = ";
    cin>>m;
    char *s1 = new char[n+1];
    char *s2 = new char[m+1];
    cout<<"输入第一个序列的元素:";
    for(int i = 1; i <= n; i++)
        cin>>s1[i];
    cout<<"输入第二个序列的元素:";
    for(int i = 1; i <= m; i++)
        cin>>s2[i];
    int **c = new int*[n+1]; ///c[i][j]存储s1[i],s2[j]的最长公共子序列长度
    int **b = new int*[n+1]; ///b[i][j]表示c[i][j]是由哪个子问题得来的,作用是方便输出,有没有无所谓。
    for(int i = 0; i <= n; i++)
    {
        c[i] = new int[m+1];
        b[i] = new int[m+1];
    }
    LCSlength(n, m, s1, s2, c, b);
    cout<<"最长子序列长度为:"<<c[n][m]<<endl;
    cout<<"一个最长子序列为:";
    print(s1, s2, n, m, c);
    cout<<endl;
    return 0;
}
void LCSlength(int n, int m, char *s1, char *s2, int **c, int **b)
{
    for(int i = 0; i <= n; i++)
        c[i][0] = 0;
    for(int i = 0; i <= m; i++)
        c[0][i] = 0;
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            if(s1[i] == s2[j])
            {
                c[i][j] = c[i-1][j-1] + 1;
                b[i][j] = 0;
            }
            else
            {
                if(c[i-1][j] > c[i][j-1])
                {
                    c[i][j] = c[i-1][j];
                    b[i][j] = 1;
                }
                else
                {
                    c[i][j] = c[i][j-1];
                    b[i][j] = 2;
                }
            }
        }
    }
}
void print(char *s1, char *s2, int nr, int mr, int **c)
{
    if(nr == 0 || mr == 0)
        return;
    if(c[nr][mr] == c[nr-1][mr-1] + 1)
    {
        print(s1,s2,nr-1,mr-1,c);
        cout<<s1[nr];
    }
    else
    {
        if(c[nr][mr] == c[nr-1][mr])
            print(s1,s2,nr-1,mr,c);
        else
            print(s1,s2,nr,mr-1,c);
    }
}

三、0/1背包的动态规划算法和程序**

算法:

程序:

///测试数据
///2 2 6 5 4
///6 3 5 4 6
#include<bits/stdc++.h>
using namespace std;
void Knapsack(int **bestValue, int n, int *weight, int *value, int Capacity);
void print(int **bv, int *w, int c, int n);
int main()
{
    int c;
    cout<<"输入背包容量:";
    cin>>c;
    int n;
    cout<<"输入物品数量:";
    cin>>n;
    int *w = new int[n+1];
    cout<<"输入每个物品的重量:"<<endl;
    for(int i = 1; i <= n; i++)
        cin>>w[i];
    int *v = new int[n+1];
    cout<<"输入每个物品的价值:"<<endl;
    for(int i = 1; i <= n; i++)
        cin>>v[i];
    int **bv = new int*[n+1];
    for(int i = 0; i <= n; i++)
        bv[i] = new int[c+1];
    Knapsack(bv, n, w, v, c);
    cout<<"背包可装入的最大价值为:"<<bv[1][c]<<endl;
    cout<<"背包装入物品的一种方案为:"<<endl;
    print(bv,w,c,n);
}
void Knapsack(int **bestValue, int n, int *weight, int *value, int Capacity)
{
    int jMax = (weight[n] - 1) < Capacity ? (weight[n] - 1) : Capacity;
    for(int i = 0; i <= jMax; i++)
        bestValue[n][i] = 0;
    for(int i = jMax +1; i <= Capacity; i++)
        bestValue[n][i] = value[n];
    for(int i = n - 1; i > 1; i--)
    {
        for(int j = 0; j <= Capacity; j++)
        {
            int temp1 = j - weight[i];
            if(temp1 < 0)
                bestValue[i][j] = bestValue[i+1][j];
            else
            {
                int temp2 = bestValue[i+1][temp1] + value[i];
                bestValue[i][j] = temp2 > bestValue[i+1][j] ? temp2 : bestValue[i+1][j];
            }
        }
    }
    bestValue[1][Capacity] = bestValue[2][Capacity];
    int temp = Capacity - weight[1];
    if(temp >= 0)
        bestValue[1][Capacity] = bestValue[1][Capacity] > ( bestValue[2][temp] + value[1]) ? bestValue[1][Capacity] : ( bestValue[2][temp] + value[1]);
}
void print(int **bv, int *w, int c, int n)
{
    int j = c;
    for(int i = 1; i < n; i++)
    {
        if(bv[i][j] == bv[i+1][j])
            continue;
        cout<<"物品"<<i<<" ";
        j = j - w[i];
    }
    if(bv[n][j] == 0)
        cout<<endl;
    else
        cout<<"物品"<<n<<endl;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!