IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 动态规划——例题 -> 正文阅读

[数据结构与算法]动态规划——例题

动态规划解题思路
总共分为四步:
1 建立一个新的一维数组或二维数组,根据题意即给出的变量来决定建立的数组类型。
2若是一维数组,确定数组第一个元素的取值。
若是二维数组,则确定数组第一行和第一列的值。
3找出状态转换方程式。
4返回结果。
例题1:求最大不连续子序列
设L=<a1,a2,…,an>是n个不同的实数的序列,L的递增子序列是这样一个子序列Lin=<aK1,ak2,…,akm>,其中k1<k2<…<km且aK1<ak2<…<akm。求最大的m值。
思路: 首先设置一个数组temp[i]用来存储到i的最长子序列。其次,初始化temp[i]={1},然后找出状态转换方程式:如果for(j=1;j<i;j++) 当arr[i]>arr[j]时,temp[i]=max(temp[i],temp[j]+1)当arr[i]<arr[j],则temp[i]不更新

#include <iostream>
#include <bits/stdc++.h>
#include <string>

using namespace std;
//测试数据
/*
4
2 1 3 50
*/
//  {2,3,50} 测试结果:3

//最长非连续子序列问题
int main()
{
    int n;
    int arr[101]; //定义数组存储序列
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>arr[i];
    }
    int temp[101]; //动态规划的第一步建立的一维数组
   for(int i=1;i<=n;i++) //对元素初始化
    temp[i]=1;
    for(int i=2;i<=n;i++)    //状态转换
    {
        for(int j=1;j<i;j++)
        {
            if(arr[i]>arr[j])
            {
                temp[i]=max(temp[i],temp[j]+1);

            }
        }
    }
    //求出temp数组的最大值
    int maxt=0;
    for(int i=1;i<=n;i++)
    {
        if(maxt<temp[i])
        {

            maxt=temp[i];
        }
    }
    cout<<maxt<<endl;
    return 0;
}

例题2:求连续最大子序列之和
给定一个整数数组 arr[] ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和.
思路:先设置一个数组temp[i]用来存储和;temp[1]初始化为arr[1];当temp[i-1]+arr[i]>arr[i],temp=temp[i-1]+arr[i],否则temp[i]=arr[i];
代码:

#include <iostream>
#include <bits/stdc++.h>
#include <string>

using namespace std;

/*测试数据
输入 :9
-2 1 -3 4 -1 2 1 -5 4

输出:6

解释:连续子序列{4 -1 2 1}和最大,为6
*/

//最大子序列和

int main()
{

    int n;
    int arr[101];  //存储原始数组
    int temp[101]; //存储和
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>arr[i];
    }
    temp[1]=arr[1]; //初始化
    for(int i=2;i<=n;i++)   //状态转换
    {

        if(temp[i-1]+arr[i]>arr[i])
            temp[i]=temp[i-1]+arr[i];
        else
            temp[i]=arr[i];
    }
    //求temp[]数组最大值
    int maxand=temp[1];
    for(int i=2;i<=n;i++)
    {
        if(temp[i]>maxand)
            maxand=temp[i];
    }
    cout<<maxand<<endl;
    return 0;

}

例题3:两个字符串最大公共子序列
给定两个字符串,求解这两个字符串的最长公共子序列(Longest Common Sequence)。比如字符串1:BDCABA;字符串2:ABCBDAB
则这两个字符串的最长公共子序列长度为4,最长公共子序列是:BCBA
思路:设置一个二维数组dp[i][j]来表示坐标(i,j)时的最长子序列。初始化第一行和一列,如果x[i]=y[j],则dp[i][j]=dp[i-1][y-1]+1;
否则的话,dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
代码:

#include <iostream>
#include <bits/stdc++.h>
#include <string>

using namespace std;

//最大公共子序列
int main()
{
    string x;
    string y;
    cin>>x;
    cin>>y;
    int dp[21][21];
    int len1=x.length();
    int len2=y.length();
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=len1;i++)
    {

        for(int j=1;j<=len2;j++)
        {
           if(x[i-1]==y[j-1])
           {
               dp[i][j]=dp[i-1][j-1]+1;
           }
           else
           {

               dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
           }
        }
    }
    cout<<dp[len1][len2]<<endl;
    int k=0;
    char temp[101];
    int p=len1-1;
    int q=len2-1;
    while(p>=0&&q>=0)
    {

        if(dp[p+1][q+1]==dp[p][q]+1&&x[p]==y[q])
        {
            temp[k++]=x[p];
            p--;
            q--;
        }
        else if(dp[p+1][q+1]==dp[p][q+1])
        {
            p--;
        }
        else
        {
            q--;
        }
    }
    for(int i=k-1;i>=0;i--)
    {
        cout<<temp[i]<<" "<<endl;
    }
    return 0;

}


例题4:找零钱问题
问题描述:
现存在一堆面值为 1,2,5,11,20,50 面值的硬币,问最少需要多少个硬币才能找出总值为 N个单位的零钱
思路:创建一个二维数组纵坐标表示硬币的面值,横坐标表示还需要找j个单位的零钱。初始化第一行第一列.对于每一种硬币,若使用这种硬币则dp[i][j]=dp[i][j-arr[i]]+dp[i-1][j],否则dp[i][j]=dp[i-1][j];
代码:

#include <iostream>
#include <bits/stdc++.h>
#include <string>

using namespace std;
/*测试样例
3
1 3 4
4
*/
// 输出:3

//找零钱问题

/*
第一行 输入面值的张数n
第二行 输入面值arr[]
第三行 输入应找的零钱数
*/
int main()
{

    int n;
    int p;
    int arr[101];
    int dp[21][21];
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>arr[i];
    }
    cin>>p;
    memset(dp,0,sizeof(dp));
    for(int i=1; i<=n; i++)
    {
        dp[i][0]=1;
    }
    for(int i=0; i<=p; i++)
    {
        if(i%arr[1]==0)
            dp[1][i]=1;
        else
            dp[1][i]=0;
    }
    for(int i=2; i<=n; i++)
    {
        for(int j=1; j<=p; j++)
        {

            if(j>=arr[i])
            {
                dp[i][j]=dp[i-1][j]+dp[i][j-arr[i]];
            }
            else
            {

                dp[i][j]=dp[i-1][j];
            }
        }
    }
    cout<<dp[n][p]<<endl;
    return 0;

}

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-08 10:59:23  更:2021-09-08 11:02:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 1:44:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码