22.4.12

1,没有上司的舞会(树形dp)2,二叉树模板;3,FBI树;4,手写哈希表;


1,没有上司的舞会

题意:

 按照闫式dp分析法:
第一步状态表示:

f[ u , 0 ] 表示在以u为根节点的子树中选,且不选u这个点的方案的集合;

f[ u , 1 ] 表示在以u为根节点的子树中选,且选u这个点的方案的集合;

所以最终答案应该是max(f[root][0], f[root][1]);

属性:max;

第二步,状态计算:
先划分集合:

先看f[u , 0 ],

因为当前u这个结点不选,所以对于它的所有子结点来说,就都有两种选择,选该子结点和不选该子结点;所以f[ u , 0 ] = max (f [ j , 1] , f[ j , 0 ] )  (j 是子结点);

f [  u,  1 ] 表示选了u这个结点,所以对于它的所有子节点来说,只有1种选择:就是不选;

f [u , 1 ] = f [ j , 0 ] ;

初始化就是f[ root ][ 1] = happy[ root ] ;

遍历所有子结点就是邻接表的遍历方式;

#include<bits/stdc++.h>
#define rep1(i,a,n) for(register int i=a;i<n;i++) 
#define rep2(i,a,n) for(register int i=a;i<=n;i++) 
#define per1(i,n,a) for(register int i=n;i>a;i--) 
#define per2(i,n,a) for(register int i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define INF 0x3f3f3f3f
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef double db;
const int N=6010;
int n;
int e[N],ne[N],h[N],idx;
bool fa[N];
int f[N][2];
int happy[N];
void add(int a,int b)
{
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u)
{
	f[u][1]=happy[u];
	for(int i=h[u];i!=-1;i=ne[i])
	{
		int j=e[i];
		dfs(j);
		f[u][1]+=f[j][0];//最终求的是 和,所以都+=
		f[u][0]+=max(f[j][0],f[j][1]);
	}
}
int main()
{	
	quick_cin();
	cin>>n;
	rep2(i,1,n)cin>>happy[i];
	memset(h,-1,sizeof h);
	rep1(i,0,n-1)
	{
		int a,b;
		cin>>a>>b;
		add(b,a);
		fa[a]=1;
	}
	int root=1;
	while(fa[root])root++;
	dfs(root);
	cout<<max(f[root][0],f[root][1]);
    return 0;
}
#include<bits/stdc++.h>
#define rep1(i,a,n) for( ll i=a;i<n;i++) 
#define rep2(i,a,n) for( ll i=a;i<=n;i++) 
#define per1(i,n,a) for( ll i=n;i>a;i--) 
#define per2(i,n,a) for( ll i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define INF 0x3f3f3f3f
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef double db;
typedef struct BTnode
{
	char data;
	BTnode *Lchild,*Rchild;
}*BinTree;
void creatBT(BinTree &BT)
{
	char c;cin>>c;
	if(c=='#')return;
	if(BT==NULL)
	{
		BT=(BTnode*)malloc(sizeof(BTnode));
		BT->data=c;
		BT->Lchild=NULL;
		BT->Rchild=NULL;
	}
	creatBT(BT->Lchild);
	creatBT(BT->Rchild);
}
int ans;
void countleaf(BinTree &BT)
{
	if(BT)
	{
		if(BT->Lchild==NULL&&BT->Rchild==NULL)
		{
			ans++;
			return;
		}
		countleaf(BT->Lchild);
		countleaf(BT->Rchild);
	}
}
void midorder(BinTree &BT)
{
	if(BT==NULL)return;
	midorder(BT->Lchild);
	cout<<BT->data;
	midorder(BT->Rchild);
}
signed main()
{	
	quick_cin();
	BTnode *BT=NULL;
	creatBT(BT);
	countleaf(BT);
	midorder(BT);
	cout<<"\n";
	cout<<ans;
	return 0;
}

3,FBI树

完全二叉树的逆推

#include<bits/stdc++.h>
#define rep1(i,a,n) for( ll i=a;i<n;i++) 
#define rep2(i,a,n) for( ll i=a;i<=n;i++) 
#define per1(i,n,a) for( ll i=n;i>a;i--) 
#define per2(i,n,a) for( ll i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define INF 0x3f3f3f3f
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef double db;
const int N=1e4+10;
char s[N];
int n;
int len;
void back(char c,int wz)
{
	if(wz>=len&&wz<=len*2-1)
	{
		if(c=='0')s[wz]='B';
		else s[wz]='I';
	}
	else
	{
		int l=wz*2;
		int r=wz*2+1;
		if(s[l]!=s[r]||s[l]=='F'||s[r]=='F')s[wz]='F';
		else 
		{
			if(s[l]=='B')s[wz]='B';
			else s[wz]='I';
		}
	}
	if(wz==1)return;
	back(c,wz/2);
}
void postorder(int wz)
{
	if(s[wz]!='c'&&wz!=len*2)
	{
		int l=wz*2;
		int r=wz*2+1;
		postorder(l);
		postorder(r);
		cout<<s[wz];
	}
}
signed main()
{	
	//quick_cin();
	cin>>n;
	memset(s,'c',sizeof s);
	len=1<<n;
	cin>>s+len;
	rep2(i,len,len+len-1)
	{
		back(s[i],i);
	}
	postorder(1);
	return 0;
}

4,哈希表

开放寻址法:解决冲突是靠找空余的位置,注意数组一般开2倍以上至少;

#include<bits/stdc++.h>
#define rep1(i,a,n) for( ll i=a;i<n;i++) 
#define rep2(i,a,n) for( ll i=a;i<=n;i++) 
#define per1(i,n,a) for( ll i=n;i>a;i--) 
#define per2(i,n,a) for( ll i=n;i>=a;i--)
#define quick_cin() cin.tie(0),ios::sync_with_stdio(false)
#define INF 0x3f3f3f3f
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef double db;
const int N=2e5+3,null=INF;
int h[N];
int find(int x)
{
	int t=(x%N+N)%N;
	while(h[t]!=null&&h[t]!=x)
	{
		t++;
		if(t==N)t=0;
	}
	return t;
}
signed main()
{		
	memset(h,0x3f,sizeof h);
	int n;
	scanf("%d",&n);
	while(n--)
	{
		char op[2];
		int x;
		scanf("%s%d",op,&x);
		if(*op=='I')h[find(x)]=x;
		else
		{
			if(h[find(x)]==null)puts("No");
			else puts("Yes");
			
		}
	}
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dull丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值