动态规划--小结

一、动态规划

1. 铁条切割

定义:r[n]表示n长的铁条最大收益

      p[i]表示i长的铁条收益

问题最优子结构:

r[j]=max(p[k]+r[j-k]),k<j

核心代码:

for(int j=1;j<n;j++)

 { for( int k=1;k<j;k++)

  {  max=p[j];

temp= p[k]+r[j-k];

if(max<temp)

     max=temp;

r[j]=max;

}

注:从长度为2的字数组开始求,然后遍历到长度为n的数组

 

 

2. 矩阵链乘问题

定义:pi表示第i个矩阵的右边维数

    m[i][j]表示第i个矩阵链乘到第j个矩阵的最小次数

问题最优子结构:

 m[i][j]=min(m[i][k]+m[k+1][j]+ pipkpj)

核心代码:

m[i][i]=0

for(intl=1;l<n;l++)

{

    min=大数;

    for(int j=1;j+l<n;j++)

     {

       for(int k=j;k<j+l;k++)

{  temp=m[j][k]+m[k][j+l]+pipkpj

              if(min< temp) 

                min=temp;

}

        m[j][j+l]=min;

}

}

3.最长公共子序列

定义:x[i],y[j]分表表示X,Y的第i个和第j个元素

     c[i][j]表示最长公共子序列长度

 

   

 

问题最优子结构:

  c[i][j]={    if(x[i]==y[j])  c[i][j]=c[i-1][j-1]+1

            else if(c[i-1][j]>c[i][j-1]) c[i][j]=c[i-1][j]

            else   c[i][j]=c[i][j-1]

典型的二维矩阵结构

当前值可以有矩阵的对角,上方,下方的值得到

首先让边界值全部为0,可以开始推

核心代码:

for(int i=1;i<=n;i++)

  for(int j=1;j<=m;j++)

   {

   if(x[i]==y[j]) c[i][j]=c[i-1][j-1]+1,,b[i][j]=x[i]

   else if(c[i-1][j]>c[i][j-1]) c[i][j]=c[i-1][j]

   else   c[i][j]=c[i][j-1]

}

扩展:

 

4.最长递增子序列

定义:f(i)表示以第i个元素为结尾的最长递增子序列长度

问题最优子结构:

f(i)=max(f(k)+1,1),if ak<ai

核心代码:

for(int i=1;i<n;i++)

    {  

           temp=1;

       for(int k=1;k<i;k++)

           if(p[k]<p[i]&&f[k]+1>temp)temp=f[k]+1;

       f[i]=temp;

     }

5.旅行商问题

 

 

6.其他问题

a. 最长回文子序列

b. 最短编辑距离

c.  最优二叉搜索树

d. 0-1背包

e. 最大字段和

f.  leetcode—120,三角形

g. 最大子数组之和、最大子数组之积

 

 

 

 

 

 

你可能感兴趣的:(动态规划--小结)