您的位置:首页 > 其它

最简单的动态规划之POJ1063

2014-04-10 11:49 288 查看
对于算法的五大分类,基本上就是递归和回溯,分治,动态规划,贪心,搜索和剪枝。

最近写程序写的少,算法看的也不多,用个最简单的程序总结一下动态规划。顺便测试一下刚刚下的Syntax Highlighter 插件好不好用。

原题见:http://acm.pku.edu.cn/JudgeOnline/problem?id=1163 求从顶端到低端的最长路径(约束条件为:沿对角线方向走)




简单的说输入就是下面下面这个下三角矩阵:

5 //As is known to all, 代表一共有5行数据

7

3 8

8 1 0

2 7 4 4

4 5 2 6 5

输出为:从顶端的7开始,沿着左斜下方或者右斜下方走,走到低端的最长路径是多少?

针对该用例的输出(用人脑走一遍,显而易见):

30

这个最简单的动态规划题目满足了动态规划的四个条件:

1. Characterize the structure of an optimal solution. 有公共的子问题

2. Recursively define the value of an optimal solution. 能递归的定义子问题的最优解

3. Compute the value of an optimal solution in a bottom-up fashion. 能自底向上的求解

4. Construct an optimal solution from computed information. 能通过计算信息构造出最优解

这里用的也是最最简单的填表法,通过输入填表,然后自底向上的构造最优解。

程序很简单,如下:

01
#include <stdio.h>
02
#include <assert.h>
03
#define MAXCOL 101
04
#define MAXROW 101
05
06
int
main()
07
{
08
int

n, num;
09
int

i = 0, j = 0;
10
int

a[MAXROW][MAXCOL];
11
int

max = 0;
12
13
scanf
(
"%d"
, &n);
14
assert
(n < MAXCOL);
15
16
for
(i = 0; i < n; i++)
17
  
for
( j = 0; j <=i; j++)
18
 
{
19
 
scanf
(
"%d"
, &num);
20
a[i][j] = num;
21
 
}
22
23
for
( i = n-2; i>=0; i--)
24
   
for
(j = 0; j <= i; j++)
25
   
{
26
 
max = a[i+1][j] > a[i+1][j+1]? a[i+1][j]: a[i+1][j+1];
27
 
a[i][j] = a[i][j] + max;
28
   
}
29
30
i++;
31
j--;
32
printf
(
"%d"
, a[i][j]);
33
34
return

0;
35
}</
assert
.h></stdio.h>
关于路径求解还有一道题,就是一个二叉树,让求从根节点到所有叶子节点中最长的路径。

思路基本上就是后序遍历,然后在遍历的过程中加入叶子节点的值,每当节点出栈的时候,相应的路径值也递减

顺手练习了两种递归的创建树的方法,第一种好一些,容易管理内存。

001
#include <cstdio>
002
#include <iostream>
003
#include <stack>
004
005
using
namespace
std;
006
007
typedef
struct
bNode
008
{
009
 
int

data;
010
 
bool

tag;
011
 
struct

bNode *left;
012
 
struct

bNode * right;
013
}BNode;
014
typedef
BNode * BTree;
015
016
//method1:create tree
017
//@param: the reference of pointer root
018
//@return: no return value
019
void
CreateTree(BTree &root)
020
{
021
  
int

data;
022
023
  
scanf
(
"%d"
, &data);
024
  
if
(data == -1)
025
 
root = NULL;
026
  
else
027
  
{
028
  
root = (BTree)
malloc
(
sizeof
(BNode));
029
  
root->data = data;
030
  
root->tag = 0;
031
  
root->left = root->right = NULL;
032
033
  
CreateTree(root->left);
034
  
CreateTree(root->right);
035
  
}
036
}
037
//@method2: Create a tree recursively
038
//@params: void
039
//@return: BNode pointer point to the root of the tree
040
BNode * CreateNode()
041
{
042
  
int

data;
043
  
scanf
(
"%d"
, &data);
044
045
  
if
(data == -1)
046
 
return

NULL;
047
  
else
048
  
{
049
  
BTree root = (BTree)
malloc
(
sizeof
(BNode));
050
  
root->data = data;
051
  
root->tag = 0;
052
  
root->left = CreateNode();
053
  
root->right = CreateNode();
054
055
  
return

root;
056
  
}
057
}
058
//@function: to get the biggest sum of the branch
059
void
BranchSum(BTree root)
060
{
061
 
stack<bnode *=
""
> s;
062
 
BTree p;
063
 
int

pathval = 0;
064
 
int

sum = 0;
065
066
 
while
(root!=NULL || (!s.empty()) )
067
 
{
068
 
while
(root!=NULL)
069
 
{
070
  
s.push(root);
071
  
pathval = pathval + root->data;
072
  
root = root->left;
073
 
}
074
 
if
(pathval > sum)
075
 
{
076
sum = pathval;
077
 
}
078
079
 
if
(!s.empty())
080
 
{
081
  
root = s.top();
082
083
  
if
(root->tag == 1)
084
  
{
085
  
printf
(
"%5d"
, root->data);
086
  
pathval = pathval - root->data;
087
  
s.pop();
088
  
root = NULL;
089
  
}
090
  
else

//turn to search the right child tree
091
  
{
092
  
root->tag = 1;
093
  
root = root->right;
094
  
}
095
 
}
096
 
}
097
   
printf
(
"\nsum is %5d\n"
, sum);
098
}
099
100
int
main()
101
{
102
BTree root = NULL;
103
printf
(
"Create a tree \n"
);
104
105
//CreateTree(root);
106
root = CreateNode();
107
BranchSum(root);
108
109
 
return

0;
110
}
111
</bnode></stack></iostream></cstdio>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: