动态规划

 
对动态规划的理解

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

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

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

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

 

 

例题

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】就是全程的一个最优值。

 

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



posted @ 2018-11-03 01:03  chenhanwu  阅读(253)  评论(0编辑  收藏  举报