动态规划(C++)

动态规划问题,大致可以分为两类:
一是最优解问题,其目的是求某个问题的最小值或最大值。
如:10000以内的k好数中任选三个的和,最大值为多少。
二是组合问题,其目的是求某个事情发生的概率。
如:长度为x的数字字符串,可以分解为4个小于255的数字,可以有多少种组合方式。
面对这两种问题的解决方案也有两种:
自上而下(记忆存储):从顶端开始分解问题,分解到最小并解决,然后返回保存的答案。如斐波拉契数列问题的递归求法便是记忆存储法。
自下而上(表格填充):先解决较小的子问题,由子问题的解推算出后续问题的解,从而得到最佳解法。如斐波拉契数列问题的递归求法便是表格填充法。
至于什么情况下使用什么方法,还需要具体情况具体分析。

数学三角形问题(动态规划);

在输入的数学三角形中寻找一条从顶部到底部的路径,使得路径上所经过的数字之和最大。路径上的每一步都只能往左下或右下行进。只需给出最大和,不需给出具体路径。
1<三角形行数<100,0<数字<99
输入格式:
5//行数
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
输出格式:
30

自顶向下的解法:

#include <iostream>
#include <vector>
using namespace std;
void math_triangle_top()
{
    //接收输入,使用2维vector存储
    int n;
    cin>>n;
    vector<vector<int>> my_vector(n);
    for (int i=0;i<my_vector.size();i++)
    {
        my_vector[i].resize(n);
    }
    //正着存的
    int k=1;
    for(int i=0;i<n;i++)
    {
         for(int j=0;j<n;j++)
        {
            if(j<k)
            {
                cin>>my_vector[i][j];
            }
            else
            {
                my_vector[i][j]=0;
            }
        }
        k+=1;

    }
    //开始一层,一层的计算,更新状态数组
    for (int i=1;i<my_vector.size();i++)
    {
        for(int j=0;j<my_vector[0].size();j++)
        {
            if(my_vector[i][j]!=0)
            {
                if(j==0)
                {
                    my_vector[i][j]+=my_vector[i-1][j];
                }
                else
                {
                     if(my_vector[i-1][j]>my_vector[i-1][j-1])
                {
                    my_vector[i][j]+=my_vector[i-1][j];
                }
                else
                {
                   my_vector[i][j]+=my_vector[i-1][j-1];
                }
                }

            }
        }

    }
    cout<<"状态数组值为:"<<endl;
    //输出状态数组中的内容
    for (int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
            cout<<my_vector[i][j]<<" ";
        cout<<endl;
    }
    //比较得出最大值
    int num_max=0;
    for (int i=0;i<n;i++)
    {
        if(num_max<my_vector[n-1][i])
        {
            num_max=my_vector[n-1][i];
        }
    }
    cout<<"最大值为:"<<endl;
    cout<<num_max;

}

自下而上的解法:

#include <iostream>
#include <vector>
using namespace std;
void math_triangle_end()
{
    //接收输入,使用2维vector存储
    int n;
    cin>>n;
    vector<vector<int>> my_vector(n);
    for (int i=0;i<my_vector.size();i++)
    {
        my_vector[i].resize(n);
    }
    //倒着存的
    int k=1;
    for(int i=my_vector.size()-1;i>=0;i--)
    {
         for(int j=0;j<my_vector[0].size();j++)
        {
            if(j<k)
            {
                cin>>my_vector[i][j];
            }
            else
            {
                my_vector[i][j]=0;
            }
        }
        k+=1;

    }
     //开始自下而上的计算,更新状态数组
    for (int i=1;i<my_vector.size();i++)
    {
        for(int j=0;j<my_vector[0].size();j++)
        {
            if(my_vector[i][j]!=0)
            {
                if(my_vector[i-1][j]>my_vector[i-1][j+1])
                {
                    my_vector[i][j]+=my_vector[i-1][j];
                }
                else
                {
                   my_vector[i][j]+=my_vector[i-1][j+1];
                }
            }
        }

    }
    //输出所有值
    cout<<"状态数组值为:"<<endl;
    for (int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
            cout<<my_vector[i][j]<<" ";
        cout<<endl;
    }
    //输出最后一个值即可
    cout<<"最大值为:"<<endl;
    cout<<my_vector[n-1][0];

}

总结:动态规划,其实就是弄一个状态矩阵,记录计算过程中每一步的计算结果,并将每次的计算结果进行一个累加,由此得到最终的答案。

电路布线动态规划(Circuit Routing with Dynamic Programming)通常用于解决电子电路设计中的布线优化问题。这个问题可以通过贪心算法动态规划来解决,其中动态规划更为精确。以下是一个简单的动态规划C++代码示例,假设我们要找到从起点到终点的最短路径,每个节点都有两种可能的连接(A和B),每条线路都有成本: ```cpp #include <vector> #include <climits> // 定义状态转移方程,dp[i][j]表示从节点i到节点j的最低成本 int dp[graphSize][graphSize]; // 动态规划函数 int circuitRouting(int start, int end, std::vector<std::vector<int>>& graph) { // 初始化边界条件 for (int i = 0; i <= end; ++i) { dp[start][i] = graph[start][i]; dp[i][end] = graph[i][end]; } // 从左到右填充动态规划表 for (int i = 1; i < graphSize; ++i) { for (int j = 0; j < i; ++j) { dp[i][j] = INT_MAX; // 假设一开始没有路径,所以设为最大值 if (i != end && j != start) { // 避免自环 dp[i][j] = std::min(dp[i][j], dp[j][end] + graph[i][j]); // 选择当前节点到终点的成本加上从j到i的成本 dp[j][i] = dp[i][j]; // 对称性,因为线路可以双向铺设 } } } return dp[end][start]; // 返回从起点到终点的最低成本 } // 示例用法 int main() { int n = 5; // 节点数量 std::vector<std::vector<int>> graph(n, std::vector<int>(n, INT_MAX)); // 初始化一个全0的图,实际应用中根据电路连接情况填充 // 填充实际的线路成本 graph = 3; graph = 2; graph = 1; graph = 4; int start = 0, end = 4; // 起点和终点 int result = circuitRouting(start, end, graph); if (result != INT_MAX) { std::cout << "Minimum cost to route from " << start << " to " << end << " is: " << result << std::endl; } else { std::cout << "No path found." << std::endl; } return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值