• 动态规划练习


    1、问题描述:一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

    例: 台阶n=0   输出:0

       台阶n=2   输出:2 

       台阶n=3   输出:3

       台阶n=4   输出:5 

       台阶n=7   输出:21

    int step(int a)
    {
        if (a <= 2)       //如果a<=2,不符合一般规律,需要先计算出这些初始值
            return a;
        int *b = new int[a + 1];
        b[0] = 0;
        b[1] = 1;
        b[2] = 2;
        for (int i = 3; i <= a; i++)
        {
            b[i] = b[i - 1] + b[i - 2]; //到第a级台阶的可能性只取决于前两级
        }
    
        return b[a];
    }
    
    int main()
    {
        int N, m;
        cout << "输入测试的样例个数:";
        while (scanf_s("%d", &N) != EOF)
        {
            cout <<endl << "输入" << N << "个数用以表示台阶数:" << endl;
            int *a = new int[N];
            for (int i = 0; i < N; i++)
            {
                cin >> m;
                *(a + i) = m;
    
            }
    
    
            cout << "跳上不同台阶的方法数:" << endl;
            for (int j = 0; j < N; j++)
            {
                cout << step(a[j])<<endl;
            }
    
        }
    }

     分别输入台阶数为4,5,6,7时跳台阶的方式数为 5、8、13、21

        

    2、问题描述:给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

    举例:
    输入:
    arr = [
      [1,3,1],
      [1,5,1],
      [4,2,1]
    ]
    输出: 7
    解释: 因为路径 13111 的总和最小。
    #include<Math.h>
    #define M 3
    #define N 4
    
    int main()
    {
        int a[M][N] = { {1,3,4,1},{1,5,6,1},{4,2,1,5} };
        //cout << a[M - 1][N - 1] << endl;
        int dp[M][N] = {};
        dp[0][0] = a[0][0];
        for (int i = 1; i < M; i++)
            dp[i][0] =dp[i-1][0]+ a[i][0];
        for (int j = 1; j < N; j++)
            dp[0][j] = dp[0][j - 1] + a[0][j];
        for (int i = 1; i < M; i++)
        {
            for (int j = 1; j < N; j++)
                
            {
                if(dp[i][j - 1] < dp[i - 1][j])
                    dp[i][j]=dp[i][j - 1] + a[i][j];
                else
                    dp[i][j]=dp[i - 1][j] + a[i][j];
            //    cout << dp[i][j]<<endl;
            }
        
        }
        cout << dp[M - 1][N - 1] << endl;
    }

    测试输出:

    3、(打家劫舍)问题描述:在⼀条直线上,有n个房屋,每个房屋中有数量不等的财宝,有⼀个盗 贼希望从房屋中盗取财宝,由于房屋中有报警器,如果同时从相邻的两个房屋中盗取财宝就会触发报警器。问在不触发报警器的前提 下,最多可获取多少财宝?例如 [5,2,6,3,1,7],则选择5,6,7

    int rob(int *a,int L)
    {
    int l = L;
    if (l == 0)
    return 0;
    
    
    int *dp=new int[l];
    dp[0] = a[0];
    if (l <2)
    return a[0];
    
    else
    {
    dp[1] = (a[0] > a[1]) ? a[0] : a[1];
    for (int i = 2; i < l; i++)
    {
    dp[i] = ((dp[i - 2] + a[i]) > dp[i - 1])? (dp[i - 2] + a[i]) : dp[i - 1];
    
    
    }
    return dp[l - 1];
    }
    
    
    }
    int main()
    {
    int L;
    int m;
    int i = 0;
    cout << "array's length: " << endl;
    //cin >>L;
    
    while (scanf_s("%d", &L) != EOF)
    {
    int *a = new int[L];
    for (; i < L; i++)
    {
    cin >> m;
    a[i] = m;
    }
    cout << rob(a, L) << endl;
    
    }

    样例输出:

     偷取3+5+7为利益最大化选择

    4、问题描述:给定⼀个数组,求这个数组的连续⼦数组中,最⼤的那⼀段的和。 如数组[-2,1,-3,4,-1,2,1,-5,4] 的⼦段 为:[-2,1]、[1,-3,4,-1]、[4,-1,2,1]、...、[-2,1,-3,4,-1,2,1,-5,4],和最⼤的是[4,-1,2,1],为6。

    int getmax_sub(int *a,int l)
    {
        if (l == 0)
            return 0;
        int *dp = new int[l];
        dp[0] = a[0];
        int max = dp[0];
        for (int i = 1; i < l; i++)
        {
            dp[i] = (dp[i - 1] + a[i]) > a[i] ? (dp[i - 1] + a[i]) : a[i];
            if (dp[i] > max)
                max = dp[i];
        
        }
    
        return max;
    }
    
    int main()
    {
        int l;
        int m;
        cout << "input array's length" << endl;
        cin >> l;
        int *a = new int[l];
        for (int i = 0; i < l; i++)
        {
            cin >> m;
            a[i] = m;
        }
        cout << getmax_sub(a, l) << endl;
    }

    样例测试运行输出:

    5、题⽬描述: 在⼀个由 0 和 1 组成的⼆维矩阵内,找到只包含 1 的最⼤正⽅形,并返回其⾯积。

    例如:
    输⼊:
    1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0 输出: 4
    int min(const int& a, const int& b)
    {
        if (a < b)
            return a;
        return b;
    }
    int max(const int& a, const int& b)
    {
        if (a > b)
            return a;
        return b;
    }
    int get_max_area(int a[][N])
    {
        if (M < 1 || N < 1)
            return 0;
        int dp[M][N] = {};
        int max_value = 0;
        for (int i = 0; i < M; i++)
            dp[i][0] = a[i][0];
        for (int j = 0; j < N; j++)
            dp[0][j] = a[0][j];
    
        for(int i=1;i<M;i++)
            for (int j = 1; j < N; j++)
            {
                if (a[i][j] == 1)
                    dp[i][j] = min(min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1])+1;
                max_value = max(dp[i][j], max_value);
            }
        return max_value*max_value;
    }
    int main()
    {
        int a[M][N] = { {1,0,1,0,0},
                        {1,0,1,1,1},
                        {1,1,1,1,1},
                        {1,0,0,1,0} };
        int max_area = get_max_area(a);
        cout << "max area :" << max_area << endl;
    }

  • 相关阅读:
    ActiveMQ中JMS的可靠性机制
    ActiveMQ中Broker的应用与启动方式
    ActiveMQ支持的传输协议
    ActiveMQ常见消息类型
    Oracle体系结构及备份(十六)——bg-ckpt
    PHP自学之路---雇员管理系统(1)
    UVa11187
    给Android组件添加事件一个很好用的方法
    【项目那些事儿】项目哪些事儿?
    struts2对拦截器使用带实例
  • 原文地址:https://www.cnblogs.com/victorywr/p/13281163.html
Copyright © 2020-2023  润新知