算法设计与分析5——动态规划

动态规划(该算法常用于求解具有某种最优性质的问题)

1、基本思想:将待求解问题分将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。

注:该问题分解得到的子问题往往不是相互独立的

在动态规划法中:我们可以用一个表记录所有以解的子问题的答案。不管这些子问题的解之后有没有被用到,只要它们被计算过就将其表格填入表中。这样在我们需要时可以直接从表中找出,避免了大量的重复计算,节省时间。所以具体的动态规划算法多种多样,但它们具有相同的填表格式。

2、设计动态规划法的步骤:

(1)找出最优解的性质,并刻画其结构特征;

(2)递归地定义最优值(写出动态规划方程);

(3)以自底向上的方式计算出最优值;

(4)根据计算最优值时得到的信息,构造一个最优解。

步骤1~3是动态规划算法的基本步骤。在只需要求出最优值的情形,步骤4可以省略;若需要求出问题的一个最优解,则必须执行步骤4。

3、动态规划算法的有效性依赖于问题本身所具有的两个重要性质

(1)优子结构:当问题的最优解包含了其子问题的最优解时,称该问题具有最优子结构性质。

(2)  重叠子问题:在用递归算法自顶向下解问题时,每次产生的子问题并不总是新问题,有些子问题被反复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只解一次,而后将其解保存在一个表格中,在以后尽可能多地利用这些子问题的解。

1、最长公共子序列问题(动态规划法)

 参考代码如下:

#include
using namespace std;
const int NUM=100;
int c[NUM][NUM];
int b[NUM][NUM];
void LCSLength(int m,int n,const char x[],const char y[])
{
    int i,j;
    for(i=1;i<=m;i++)c[i][0]=0;
    for(j=1;j<=n;j++)c[0][j]=0;
    for(i=1;i<=m;i++)
        for(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 LCS(int i,int j,char x[])
{
    if(i==0||j==0)return ;
    if(b[i][j]==1){
        LCS(i-1,j-1,x);
        cout<     }else if(b[i][j]==2){
        LCS(i-1,j,x);
    }else LCS(i,j-1,x);
}
int main()
{
    int num1,num2;
    cin>>num1>>num2;
    char ch_x[100],ch_y[100];
    for(int i=1;i<=num1;i++)
        cin>>ch_x[i];
    for(int j=1;j<=num2;j++)
        cin>>ch_y[j];
    LCSLength(num1,num2,ch_x,ch_y);
    LCS(num1,num2,ch_x);
}
 

 2、最大子段和问题(动态规划法)

 参考代码如下:

#include
using namespace std;
const int NUM=100;
int a[NUM];
int MaxSum(int n,int&besti,int&bestj)
{
    int sum=0;
    int b=0;
    int begin=0;
    for(int i=1;i<=n;i++)
    {
        if(b>0)b+=a[i];
        else {b=a[i];begin=i;}
        if(b>sum)
        {
            sum=b;
            besti=begin;
            bestj=i;
        }
    }
    return sum;
}
int main()
{
    int num;
    int i,j;
    cin>>num;
    for(int k=1;k<=num;k++)
        cin>>a[k];
    int temp;
    temp=MaxSum(num,i,j);
    cout<     cout< }
 

 

 

 

 

 

 

 

你可能感兴趣的:(算法设计与分析)