动态规划法将待求解问题分解成若干个相互重叠的子问题,每个子问题对应决策过程的一个阶段,一般来说,子问题的重叠关系表现在对给定问题求解的递推关系(也就是动态规划函数)中,将子问题的解求解一次并填入表中,当需要再次求解此子问题时,可以通过查表获得该子问题的解而不用再次求解,从而避免了大量重复计算。
动态规划法设计算法一般分成三个阶段:
(1)分段:将原问题分解为若干个相互重叠的子问题;
(2)分析:分析问题是否满足最优性原理,找出动态规划函数的递推式;
(3)求解:利用递推式自底向上计算,实现动态规划过程。
数塔
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 12856 Accepted Submission(s): 7639
有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少?

1 /*
2 写于2013年1月15日
3 练习DP,通俗的数塔问题
4 也可自底向上 map[i][j]=data[i][j]+max(map[i+1][j],map[i+1][j+1])
5 */
6 #include <iostream>
7 #include <stdio.h>
8 #include <math.h>
9 using namespace std;
10
11 int data[105][105]; //存放初始数据
12 int map[105][105]; //存放路径上的和
13 int main()
14 {
15 int n,c;
16 while(scanf("%d",&c)!=EOF)
17 {
18 while(c--)
19 {
20 scanf("%d",&n);
21 for(int i=1;i<=n;i++)
22 for(int j=1;j<=i;j++)
23 {
24 scanf("%d",&data[i][j]);
25 }
26 map[1][1]=data[1][1];
27 for(int i=2;i<=n;i++)
28 for(int j=1;j<=i;j++)
29 {
30 //每点的路径和等于该节点data值与上层邻接map中的最大值之和
31 map[i][j]=data[i][j]+max(map[i-1][j],map[i-1][j-1]);
32 }
33 int maxn=0;
34 for(int j=1;j<=n;j++)//遍历最后一行找到找到路径最大值
35 maxn=max(maxn,map[n][j]);
36 printf("%d\n",maxn);
37 }
38 }
39 return 0;
40 }
命运
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5353 Accepted Submission(s): 1881

1 #include <iostream>
2 #include <stdio.h>
3 #include <iostream>
4 #include <string.h>
5 using namespace std;
6 int data[25][1005]; //存放初始数据
7 int map[25][1005]; //存放路径分数值
8 int main()
9 {
10 int c;
11 while(scanf("%d",&c)!=EOF)
12 {
13 int n,m;
14 for(int k=0;k<c;k++)
15 {
16 int maxn;
17 scanf("%d%d",&n,&m);
18 for(int j=0;j<=m;j++)
19 map[0][j]=-999;//对0行0列设置最小量
20 for(int i=0;i<=n;i++)
21 map[i][0]=-999;
22 for(int i=1;i<=n;i++)
23 for(int j=1;j<=m;j++)
24 {
25 scanf("%d",&data[i][j]);
26 }
27 //map[1][1]=data[1][1];
28 for(int i=1;i<=n;i++)
29 for(int j=1;j<=m;j++)
30 {
31 maxn=-999;
32 for(int p=1;p<j;p++)//找到每行的最大值
33 {
34 if(j%p==0||j-p==1)
35 maxn=max(maxn,map[i][p]);
36 }
37 if(i==1&&j==1)//i=1,j=1时,对map初始化
38 map[1][1]=data[1][1];
39 else
40 map[i][j]=data[i][j]+max(maxn,map[i-1][j]);//找到i,j时的最大值
41 }
42 printf("%d\n",map[n][m]);
43 }
44 }
45 //cout << "Hello world!" << endl;
46 return 0;
47 }