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;
}