DP动态规划学习笔记

理解:

   求当前状态的解,应该由子状态的解来得出,即:先必须求出子状态的解。一次往前递推,一般可由最最小的子问题(最易分析出结果,不可再分)逐层求出。

   举个例子。

   15=14+1;  

   14=13+1;

     13=12+1;

     ......

   2=1+1;

    橙色的1期为之前提到的最最小的子问题。

    分析:要求出15,可以分解成14+1;要求出14,可以分解成求出13,再加上1.

       所以说先从最简单的2开始求。

一维DP问题:

    最长非降子序列

  a[0]  a[1]  a[2]  a[3]  a[4]  a[5]  a[6]

  5    3     4    8     7    9    3 

  d[i]表示以a[i]为结尾的最长非降子序列的长度。

  d[0]  = 1  序列:5

  d[1]  = 1  序列:3    因为5>3

  d[2]  = 2  序列:3 4

  d[3]  = 3  序列:3 4 8

  ........

  不难得出,d[i]等于1(此时,a[i]的值比它前面任何一个数都小,所以只能a[i]它自己构成一个非降子序列)

            或者是 max{  d[j]+1 } j的取值为:所有满足a[j]<=a[i]的j.     例:d[4]=max{ d[0]+1 ,d[1]+1 ,d[2]+1 }

  代码:

 1 //DP动态规划 最长非降子序列
 2 #include<iostream>
 3 using namespace std;
 4 int main()
 5 {
 6     int a[100];
 7     int n;
 8     cin>>n;
 9     int i;
10     for(i=0;i<n;i++)
11         cin>>a[i];
12     int d[n];
13     d[0]=1;
14     int j;
15     for(i=1;i<n;i++)
16     {
17         d[i]=1;
18         for(j=i-1;j>=0;j--)
19         {
20             if(a[j]<=a[i])
21             {
22                 if(d[j]+1>d[i]) d[i]=d[j]+1;
23             }
24         }
25         cout<<i<<" "<<d[i]<<endl;
26     }
27     return 0;
28 } 

二维DP问题:

      平面上有m*n个格子,每个格子中放着一定数量的苹果。你从左上角的格子开始,每一步只能是向下走或是向右走,每次走到一个格子上就把格子里的苹果收集起来,这样下去最多能收集到多少个苹果。

 

 1 //DP 苹果问题
 2 #include<iostream>
 3 using namespace std;
 4 int main()
 5 {
 6     int a[100][100];
 7     int m,n,max;
 8     cin>>m>>n;
 9     int i,j,k;
10     for(i=0;i<m;i++)
11     {
12         for(j=0;j<n;j++)
13             cin>>a[i][j];
14     }
15     int s[m][n]={0,0,0};
16     for(i=0;i<m;i++)
17     {
18         for(j=0;j<n;j++)
19         {
20             
21             if(i==0&&j==0) max=0;
22             else if(i>0&&j==0) max=s[i-1][j];
23             else if(i==0&&j>0) max=s[i][j-1];
24             else if(s[i-1][j]>s[i][j-1]) max=s[i-1][j];
25             else max=s[i][j-1];
26             s[i][j]=max+a[i][j];
27         }
28     }
29     for(i=0;i<m;i++)
30     {
31         for(j=0;j<n;j++)
32         {
33             if(j==0) cout<<s[i][j];
34             else cout<<" "<<s[i][j];
35         }
36         cout<<endl;
37     }
38 }

 

 

posted @ 2017-09-13 17:15  Elaine_DWL  阅读(93)  评论(0编辑  收藏  举报