zoukankan      html  css  js  c++  java
  • 算法导论 动态规划

    动态规划:dynamic programming

    dp:

    最优子结构

    重叠子问题

    独立子问题

    步骤:

    1.描述一个最优子结构

    2.递归定义最优解

    3.自底向上求出最优解的值

    4.按要求求出一个最优解

    其时间效率为:  有多少子问题*这些子问题分别有多少选择

    总结:还挺好玩,感觉和高中的推理差不多,只是要深植于   找到特征+找到最优子结构+描述最优子结构+递归定义+求解+加上路径数组来构造最优解。

    从前几项的关系得出推理:

    从本问题可以被分为几个问题来得出推理

    从要求的最后一项往前推

    装配线调度:

     1 #include <iostream>
     2 #include <cstdio>
     3 
     4 using namespace std;
     5 
     6 int main()
     7 {
     8     int e1,e2,x1,x2,a1[7],a2[7];
     9     int f[2][7],fe,le,l[2][7],t1[7],t2[7];
    10     scanf("%d%d",&e1,&e2);
    11     scanf("%d%d",&x1,&x2);
    12     for(int i=1;i<=6;i++)
    13         scanf("%d",&a1[i]);
    14     for(int i=1;i<=6;i++)
    15         scanf("%d",&a2[i]);
    16     for(int i=1;i<=5;i++)
    17         scanf("%d",&t1[i]);
    18     for(int i=1;i<=5;i++)
    19         scanf("%d",&t2[i]);
    20     f[1][1]=e1+a1[1];
    21     f[2][1]=e2+a2[1];
    22     
    23     for(int j=2;j<=6;j++)
    24     {
    25         if(f[1][j-1]+a1[j]<=f[2][j-1]+t2[j-1]+a1[j])
    26         {
    27             f[1][j]=f[1][j-1]+a1[j];
    28             l[1][j]=1;
    29         }
    30         else
    31         {
    32             f[1][j]=f[2][j-1]+t2[j-1]+a1[j];
    33             l[1][j]=2;
    34         }
    35         
    36         if(f[2][j-1]+a2[j]<=f[1][j-1]+t1[j-1]+a2[j])
    37         {
    38             f[2][j]=f[2][j-1]+a2[j];
    39             l[2][j]=2;
    40         }
    41         else
    42         {
    43             f[2][j]=f[1][j-1]+t1[j-1]+a2[j];
    44             l[2][j]=1;
    45         }
    46     }
    47     if(f[1][6]+x1<=f[2][6]+x2)
    48     {
    49         fe=f[1][6]+x1;
    50         le=1;
    51     }
    52     else
    53     {
    54         fe=f[2][6]+x2;
    55         le=2;
    56     }
    57     
    58     printf("%d
    ",fe);
    59     
    60     int i=le;
    61     printf("print line %d,station %d
    ",i,6);
    62     for(int j=6;j>=2;j--)
    63     {
    64         i=l[i][j];
    65         printf("print line %d,station %d
    ",i,j-1);
    66     }
    67     return 0;
    68 }
    源码实现

    矩阵链乘法

    节省了常数递归时间,还可以根据存取模式进行求解。

     1 #include <iostream>
     2 #include <cstdio>
     3 #define inf 1e9
     4 using namespace std;
     5 int s[7][7];
     6 void print_optimal_parens(int i,int j)
     7 {
     8     if(i==j)
     9         printf("A%d",i);
    10     else
    11     {
    12         printf("(");
    13         print_optimal_parens(i,s[i][j]);
    14         print_optimal_parens(s[i][j]+1,j);
    15         printf(")");
    16     }
    17         
    18 }
    19 
    20 int main()
    21 {
    22     int p[7];
    23     for(int i=0;i<=6;i++)
    24         scanf("%d",&p[i]);
    25     
    26     int m[7][7];
    27     for(int i=1;i<=6;i++)
    28         m[i][i]=0;
    29     for(int l=2;l<=6;l++)
    30     {
    31         for(int i=1;i<=6-l+1;i++)
    32         {
    33             int j=i+l-1;
    34             m[i][j]=inf;
    35             for(int k=i;k<=j-1;k++)
    36             {
    37                 int q=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
    38                 if(q<m[i][j])
    39                 {
    40                     m[i][j]=q;
    41                     s[i][j]=k;
    42                 }
    43             }
    44         }
    45     }
    46     printf("%d
    ",m[1][6]);
    47     
    48     print_optimal_parens(1,6);
    49     return 0;
    50 }
    View Code

     做备忘录的自顶向下的递归法时间效率O(n^3)

    可以对一些子问题根本不需要求解的问题避免求解。

     1 #include <iostream>
     2 #include <cstdio>
     3 #define inf 1e9
     4 using namespace std;
     5 int s[7][7];
     6 int p[7];
     7 int m[7][7];
     8 void print_optimal_parens(int i,int j)
     9 {
    10     if(i==j)
    11         printf("A%d",i);
    12     else
    13     {
    14         printf("(");
    15         print_optimal_parens(i,s[i][j]);
    16         print_optimal_parens(s[i][j]+1,j);
    17         printf(")");
    18     }
    19         
    20 }
    21 
    22 int lookup_chain(int i,int j)
    23 {
    24    if(m[i][j]<inf)
    25        return m[i][j];
    26     if(i==j)
    27         m[i][j]=0;
    28     for(int k=i;k<=j-1;k++)
    29     {
    30         int q=lookup_chain(i,k)+lookup_chain(k+1,j)+p[i-1]*p[k]*p[j];
    31         if(q<m[i][j])
    32         {
    33             m[i][j]=q;
    34             s[i][j]=k;
    35         }
    36     }
    37     return m[i][j];
    38 }
    39 
    40 void memorzed_matrix_chain()
    41 {
    42     for(int i=1;i<=6;i++)
    43         for(int j=i;j<=6;j++)
    44             m[i][j]=inf;
    45     lookup_chain(1,6);
    46 }
    47 
    48 
    49 
    50 
    51 int main()
    52 {
    53     for(int i=0;i<=6;i++)
    54         scanf("%d",&p[i]);
    55     memorzed_matrix_chain();
    56     printf("%d
    ",m[1][6]);
    57     
    58     print_optimal_parens(1,6);
    59     return 0;
    60 }
    View Code

    最长公共子序列的实现算法:加打印最优解

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <string>
     5 
     6 using namespace std;
     7 
     8 void print_lcs(int b[][5],char x[],int i,int j)
     9 {
    10     if(i==-1 || j==-1)
    11         return;
    12     if(b[i][j]==1)
    13     {
    14         printf("%c",x[i]);
    15         print_lcs(b,x,i-1,j-1);
    16     }
    17     else if(b[i][j]==2)
    18         print_lcs(b,x,i-1,j);
    19     else if(b[i][j]==3)
    20         print_lcs(b,x,i,j-1);
    21     
    22 }
    23 int lcs(char x[],char y[])
    24 {
    25     int m=strlen(x);
    26     int n=strlen(y);
    27     int c[m+1][n+1];
    28     int b[8][5];
    29     for(int i=0;i<=m;i++)
    30         c[i][0]=0;
    31     for(int i=0;i<=n;i++)
    32         c[0][i]=0;
    33     
    34     for(int i=0;i<m;i++)
    35     {
    36         for(int j=0;j<n;j++)
    37         {
    38             if(x[i]==y[j])
    39             {
    40                 c[i+1][j+1]=c[i][j]+1;
    41                 b[i][j]=1;
    42             }
    43             
    44             else if(c[i][j+1]>=c[i+1][j])
    45             {
    46                 c[i+1][j+1]=c[i][j+1];
    47                 b[i][j]=2;
    48             }
    49             else if(c[i][j+1]<c[i+1][j])
    50             {
    51                 c[i+1][j+1]=c[i+1][j];
    52                 b[i][j]=3;
    53             }
    54         }
    55     }
    56     print_lcs(b,x,m-1,n-1);
    57     puts("");
    58     return c[m][n];
    59 }
    60 int main()
    61 {
    62     char x[]="ABCBDAB";
    63     char y[]="ABCB";
    64     int LCS=lcs(x,y);
    65     printf("%d
    ",LCS);
    66     return 0;
    67 }
    View Code

    最优二叉搜索树

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <string>
     5 #define inf 0x3f3f3f3f
     6 using namespace std;
     7 
     8 
     9 float optimal_bst(float p[],float q[],int n)
    10 {
    11     float e[n+2][n+2],w[n+2][n+2];
    12     int root[7][7];
    13     
    14     for(int i=1;i<=n+1;i++)
    15     {
    16         e[i][i-1]=q[i-1];
    17         w[i][i-1]=q[i-1];
    18     }
    19     
    20     for(int l=1;l<=n;l++)
    21     {
    22         for(int i=1;i<=n-l+1;i++)
    23         {
    24             int j=i+l-1;
    25             e[i][j]=inf;
    26             w[i][j]=w[i][j-1]+p[j]+q[j];
    27             for(int r=i;r<=j;r++)
    28             {
    29                 float t=e[i][r-1]+e[r+1][j]+w[i][j];
    30                 if(t<e[i][j])
    31                 {
    32                     e[i][j]=t;
    33                     root[i][j]=r;
    34                 }
    35             }
    36         }
    37     }
    38     return e[1][n];
    39 }
    40 
    41 
    42 int main()
    43 {
    44     float q[7],p[7];
    45     for(int i=1;i<=5;i++)
    46         scanf("%f",&p[i]);
    47     for(int i=0;i<=5;i++)
    48         scanf("%f",&q[i]);
    49     printf("%f
    ",optimal_bst(p,q,5));
    50     return 0;
    51 }
    View Code
    活在现实,做在梦里。
  • 相关阅读:
    问题 Duplicate entry '0' for key 'PRIMARY'
    java中转译符用"\"的几种特殊字符
    mysql在查询中常见问题汇总
    linux msql
    shell 简单的比大小脚本
    wordpress的备份与还原
    wordpress的创建
    6、httpd服务的安装、配置
    5、Linux下面桌面的安装
    4、时间同步ntp服务的安装于配置(作为客户端的配置)
  • 原文地址:https://www.cnblogs.com/do-it-best/p/5463667.html
Copyright © 2011-2022 走看看