1、求二叉树的最大子树和,节点有正有负。
long max_sum = numeric_limits<long>::min();
TreeNode *sub_root = NULL;
long Max_sub_tree(TreeNode *root){
if (NULL == root) {
sub_root = root;
return 0;
}
long left_sum = Max_sub_tree(root->left); //左子树的总和(计算总和过程中可能已经更新了当前的最大值和子树)
long right_sum = Max_sub_tree(root->right); //再计算右子树
long sum = root->data + left_sum + right_sum;
if (sum >= max_sum) {
max_sum = sum;
sub_root = root;
}
return sum;
}
int Max_sub_tree_sum(TreeNode *root){
long sum = Max_sub_tree_sum(&root);
return max_Sum;
}
2、平面上有N*M个格子,每个格子中放着一定数量的苹果。你从左上角的格子开始,每一步只能向下走或是向右走,每次走到一个格子上就把格子里的苹果收集起来,这样下去,你最多能收集到多少个苹果。
典型动态规划,思路是想找到“状态”,再找到“状态转移方程”,基本这道题目就解决了。
状态S[i][j]表示我们走到(i, j)这个格子时,最多能收集到多少个苹果。那么,状态转移方程如下:
S[i][j]=A[i][j] + max(S[i-1][j], if i>0 ; S[i][j-1], if j>0)
其中i代表行,j代表列,下标均从0开始;A[i][j]代表格子(i, j)处的苹果数量。
S[i][j]有两种计算方式:1.对于每一行,从左向右计算,然后从上到下逐行处理;2. 对于每一列,从上到下计算,然后从左向右逐列处理。这样做的目的是为了在计算S[i][j]时,S[i-1][j]和S[i][j-1]都已经计算出来了。
算法代码如下:
int getMaxApple(int n,int m){
int arr[ n ][ m ] = { 0 };
int dp[ n+ 2 ][m + 2 ] = { 0 };
int i, j ;
for( i = 0; i < n; i++){
for( j = 0; j < m; j++)
cin>> arr[ i ][ j ];
} //输入方格中各个格子中的苹果数量
for( i = 0; i < n; i++){
for( j = 0; j < m; j++){
dp[ i + 1 ][ j + 1 ] = dp[ i ][ j + 1] > dp[ i + 1 ][ j ] ?
dp[ i ][ j + 1] + arr[ i ][ j ] : dp[ i + 1][ j ] + arr[ i ][ j ];
}
}
cout<<dp[i][j]<<endl;
return 0;
}</span>