• 动态规划


     
    对动态规划的理解

    多态规划是通过将一个大的问题分为多个子问题,并且将子问题再进行划分,一直到求得每个子问题的最优解,

    在这个过程中登记子问题的解,不进行子问题的重复计算,大大提升了计算速度。

    动态规划分为很种类型的问题,一个问题能否看成一个动态规划的问题,主要看它是否存在

    这重复子问题以及最优子结构。

    例题

    7-1 单调递增最长子序列 (20 分)

    设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。

    输入格式:

    输入有两行: 第一行:n,代表要输入的数列的个数 第二行:n个数,数字之间用空格格开

    输出格式:

    最长单调递增子序列的长度

    输入样例:

    在这里给出一组输入。例如:

    5
    1 3 5 2 9
    

    输出样例:

    在这里给出相应的输出。例如:

    4


     1 #include <iostream>
     2 using namespace std;
     3 int main()
     4 {
     5     int *a,*count;
     6     int n;
     7     cin>>n;
     8     a=new int [n];
     9     count=new int [n];
    10     for(int i=0;i<n;i++)
    11     {
    12         count[i]=1;
    13     }
    14     for(int i=0;i<n;i++)
    15     {
    16         cin>>a[i];
    17     }
    18     for(int i=0;i<n;i++)
    19     {
    20         int k=i+1;
    21         for(int j=i;j<n-1;)
    22         {
    23             if(a[j]<a[k])
    24             {
    25                 count[i]++;
    26                 j=k;
    27                 k++;
    28             }
    29             else
    30             {
    31                 k++;
    32             }
    33         }
    34      } 
    35      int max=count[0];
    36      for(int i=1;i<n;i++)
    37      {
    38          if(max<count[i])
    39          {
    40              max=count[i];
    41          }
    42      }
    43     cout<<max<<endl;
    44     return 0;
    45 }

    思想:

    设置一个 k 下标,定位移动,当前者小于后者的时候,将k赋值给j, 

    否则就将j定位在当前的 k 的位置,而 k 持续下移,知道出现一个比 j 定位的地方大的数字

    7-2 租用游艇问题 (17 分)

    题目来源:王晓东,《算法设计与分析》

    长江游艇俱乐部在长江上设置了n个游艇出租站1,2,…,n。游客可在这些游艇出租站租用游艇,并在下游的任何一个游艇出租站归还游艇。游艇出租站i到游艇出租站j之间的租金为r(i,j),1<=i<j<=n。试设计一个算法,计算出从游艇出租站1 到游艇出租站n所需的最少租金。

    输入格式:

    第1 行中有1 个正整数n(n<=200),表示有n个游艇出租站。接下来的第1到第n-1 行,第i行表示第i站到第i+1站,第i+2站, ... , 第n站的租金。

    输出格式:

    输出从游艇出租站1 到游艇出租站n所需的最少租金。

    输入样例:

    在这里给出一组输入。例如:

    3
    5 15
    7
    

    输出样例:

    在这里给出相应的输出。例如:

    12
     1 #include <iostream>
     2 using namespace std;
     3 int main()
     4 {
     5     int n;
     6     cin>>n;
     7     int *A[n+1];
     8     for(int i=0;i<=n;i++)
     9     {
    10         A[i]=new int [n+1];
    11     }
    12     for(int i=1;i<=n;i++)
    13     {
    14         A[i][i]=0;
    15     }
    16     for(int i=1;i<n;i++)
    17     {
    18         for(int j=i+1;j<=n;j++)
    19         {
    20             cin>>A[i][j];
    21         }
    22     }
    23     
    24     for(int i=2; i<=n; i++){
    25         for(int j=i+1; j<=n; j++){
    26             int k=j-i;
    27             for(int p=k;p<j;p++)
    28                 if(A[k][p]+A[p][j]<A[k][j])//取最小
    29                     A[k][j]=A[k][p]+A[p][j];
    30         }
    31     }
    32     cout<<A[1][n]<<endl;
    33     return 0;
    34 }

    思想:弃用0下标,

    这是一个动态规划问题,从左往右,从下往上添加矩阵,在此处选用了斜对角线添加的方式,矩阵中的每个点都选出它最小的价格填进去,知道最后A【1】【n】就是全程的一个最优值。

     

    结对编程的情况:两个人之间相辅相成,在解题过程中有着不可或缺的作用、



  • 相关阅读:
    java 单向链表实现
    super、this
    Java程序员们最常犯的10个错误
    Codeforces-1323D Present
    Codeforces-1323E Instant Noodles
    Codeforces-1312E Array Shrinking
    Codeforces-1327D Infinite Path
    Codeforces-1326D Prefix-Suffix Palindrome
    HDU-5885 XM Reserves
    NTT(快速数论变换)用到的各种素数及原根
  • 原文地址:https://www.cnblogs.com/chenhanwu/p/9899268.html
Copyright © 2020-2023  润新知