我是靠谱客的博主 孤独纸鹤,最近开发中收集的这篇文章主要介绍[CodeForces815C] Karen and Supermarket[CodeForces212E] IT Restaurants 树形背包模板两道,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

传送:815C 

           212E

树形背包的本质就是树形dp,但是dp的时候考虑是否取某个子树当前状态,取法和一维背包类似。

T1:不难发现一个性质,我们取到两种颜色和一定为N-1。那么树形背包带进来,flag记录答案是否合法。

T2:这题相对模板一点,DP开到三维,多出来的一维表示这个状态是否已经用了优惠券。

今天的博客好捞啊。

T1代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 5005
using namespace std;
inline void read(int &x){
x=0;int f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
x*=f;
}
struct node{
int nex,to;
}edge[maxn<<1];
int head[maxn],tot;
bool flag[maxn];
int N;
inline void insert(int from,int to){
edge[++tot].nex=head[from];
head[from]=tot;
edge[tot].to=to;
}
int siz[maxn],dp[maxn][maxn];
void dfs(int x,int u){
siz[x]=1;
dp[x][0]=1;
for(int i=head[x];i;i=edge[i].nex)
if(edge[i].to^u)
{
dfs(edge[i].to,x);
siz[x]+=siz[edge[i].to];
for(int k=N-1;k>=0;k--)
if(dp[x][k])
dp[x][k+siz[edge[i].to]]=1;
}
int high=N-siz[x];
for(int i=N-1;i>=0;i--)
if(dp[x][i])
dp[x][i+high]=1;
for(int i=1;i<N-1;i++)
if(dp[x][i])
flag[i]=1;
}
int main(){
read(N);
int u,v;
for(int i=1;i<N;i++){
read(u);read(v);
insert(u,v);
insert(v,u);
}
dfs(1,1);
int ans=0;
for(int i=1;i<N-1;i++)
if(flag[i])
ans++;
cout<<ans<<endl;
for(int i=1;i<N-1;i++)
if(flag[i])
cout<<i<<" "<<N-i-1<<endl;
}
View Code

T2代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 5005
using namespace std;
inline void read(int &x){
x=0;int f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
x*=f;
}
struct node{
int nex,to;
}edge[maxn<<1];
int head[maxn],tot;
int N,B;
inline void insert(int from,int to){
edge[++tot].nex=head[from];
head[from]=tot;
edge[tot].to=to;
}
int c[maxn],d[maxn];
int dp[2][maxn][maxn],siz[maxn];
void dfs(int x)
{
dp[0][x][0]=0;
dp[0][x][1]=c[x];
dp[1][x][1]=c[x]-d[x];
siz[x]=1;
for(int i=head[x];i;i=edge[i].nex)
{
dfs(edge[i].to);
for(int j=siz[x];j>=0;j--)
for(int k=0;k<=siz[edge[i].to];k++)
{
dp[0][x][j+k]=min(dp[0][x][j+k],dp[0][x][j]+dp[0][edge[i].to][k]);
dp[1][x][j+k]=min(dp[1][x][j+k],dp[1][x][j]+dp[1][edge[i].to][k]);
dp[1][x][j+k]=min(dp[1][x][j+k],dp[1][x][j]+dp[0][edge[i].to][k]);
}
siz[x]+=siz[edge[i].to];
}
}
int main()
{
memset(dp,0x3f,sizeof(dp));
read(N);read(B);
read(c[1]);read(d[1]);
int u;
for(int i=2;i<=N;i++)
{
read(c[i]);read(d[i]);
read(u);
insert(u,i);
}
dfs(1);
int ans=N;
while(dp[0][1][ans]>B&&dp[1][1][ans]>B)
ans--;
cout<<ans;
}
View Code

 

转载于:https://www.cnblogs.com/sherrlock/p/9833303.html

最后

以上就是孤独纸鹤为你收集整理的[CodeForces815C] Karen and Supermarket[CodeForces212E] IT Restaurants 树形背包模板两道的全部内容,希望文章能够帮你解决[CodeForces815C] Karen and Supermarket[CodeForces212E] IT Restaurants 树形背包模板两道所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(54)

评论列表共有 0 条评论

立即
投稿
返回
顶部