1.题目:
打家劫舍 (3) 加强加强版
在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为“根”。除了“根”之外,每栋房子有且只有一个“父“房子与之相连。
一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。如果两个直接相连的房子在同一天晚上被打劫,房屋将自动报警。
计算在不触动警报的情况下,小偷一晚能够盗取的最高金额。
2.算法:
1.递归+ dfs + 动态规划
3.算法思想:
和之前的问题的解决思路差不多!,,
1.判断这个节点 选与不选的 最优解是谁!
2.从低位一直 形成最优解 到高位,方便调用!!
4.代码:
/*************************************************
作者:She001
时间:2022/9/7
题目:打家劫舍 (3) 加强加强版
在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为“根”。除了“根”之外,每栋房子有且只有一个“父“房子与之相连。
一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。如果两个直接相连的房子在同一天晚上被打劫,房屋将自动报警。
计算在不触动警报的情况下,小偷一晚能够盗取的最高金额。
算法:
2.dfs + 动态规划
***************************************************/
#include<bits/stdc++.h>
using namespace std;
typedef struct student
{
int a;
struct student * left;
struct student * right;
int shendu;//树的深度
}node; //指针类型的
/*//二叉树模型
a1
a2 a3
a4 a5 a6 a7
a8
a9
*/
///
//算法:
//1. 递归
int max(int a,int b)//两个数,返回最大的数
{
if(a>b)
{
return a;
}
else
{
return b;
}
}
//算法:迭代动态规划:
int * fangfa_1_1(node* n)
{
int *ww = new int[2];
if(n ==NULL)
{
ww[0]=0;//这个节点选了 的金额总数
ww[1]=0;//这个节点没选的金额总数
return ww;
}
int * l=fangfa_1_1(n->left);//递归调用
int * r=fangfa_1_1(n->right);//递归调用
int select =n->a + l[1] + r[1];//计算选择了当前节点 能得到的金额数目
int noselect=max(l[0],l[1]) + max(r[0],r[1]);//没有选着当前节点能得到的金额数目
delete[] l;//摧毁当前节点的子节点的存储空间
delete[] r;//摧毁当前节点的子节点的存储空间
ww[0]=select;//选择这个节点的最大金额存储到 0
ww[1]=noselect;//把没有选择这个节点的最大金额存储到 1
return ww;
}
int fangfa_1(node * n)
{
int *m=fangfa_1_1(n);
int mm=max(m[0],m[1]);
delete[] m;
return mm;
}
int main()
{
//数据初始化,建立树
struct student *a1 =new struct student;
struct student *a2 =new struct student;
struct student *a3 =new struct student;
struct student *a4 =new struct student;
struct student *a5 =new struct student;
struct student *a6 =new struct student;
struct student *a7 =new struct student;
struct student *a8 =new struct student;
struct student *a9 =new struct student;
//数值的赋值
a1->a=1;
a2->a=2;
a3->a=3;
a4->a=4;
a5->a=5;
a6->a=6;
a7->a=7;
a8->a=8;
a9->a=9;
//节点的连接
a1->left=a2;
a1->right=a3;
a2->left=a4;
a2->right=a5;
a3->left=a6;
a3->right=a7;
a6->left=a8;
a8->right=a9;
//节点为空的设置
a4->left=NULL;
a4->right=NULL;
a5->left=NULL;
a5->right=NULL;
a8->left=NULL;
a9->left=NULL;
a9->right=NULL;
a6->right=NULL;
a7->left=NULL;
a7->right=NULL;
int a=fangfa_1(a1);
cout<<"a= "<<a<<endl;//预测 是 32
return 0;
}