专栏文章
题解:P12136 [蓝桥杯 2025 省 B] 生产车间
P12136题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minkbmy7
- 此快照首次捕获于
- 2025/12/02 03:49 3 个月前
- 此快照最后确认于
- 2025/12/02 03:49 3 个月前
题意化简
选择一些叶子节点,使得每个非叶子节点,它对应的子树中的已选叶子节点的权值和小于 。
值得注意的是原题中一个点如果被删去了所有叶子节点,它并不会成为一个产出材料的叶子节点。
值得注意的是原题中一个点如果被删去了所有叶子节点,它并不会成为一个产出材料的叶子节点。
思路分析
设 表示 这个节点所有的可能取值, 代表这个取值是可能的。
转移的复杂度为 ,但是因为有 的剪枝就可以通过此题。
转移的复杂度为 ,但是因为有 的剪枝就可以通过此题。
Solution
朴素实现:
CPP#include<bits/stdc++.h>
using namespace std;
const int N=1005;
int n,a[N];
bool f[N][N];
vector<int> e[N],tmp;
void dfs(int x,int fa)
{
if(e[x].size()==1&&x!=1) f[x][a[x]]=true;//注意有可能是一条链
f[x][0]=true;
for(auto u:e[x])if(u!=fa)
{
dfs(u,x);
tmp.clear();
for(int i=0;i<=a[x];i++)if(f[x][i])for(int j=0;i+j<=a[x];j++)if(f[u][j]) tmp.push_back(i+j);
for(auto y:tmp) f[x][y]=true;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1,x,y;i<n;e[x].push_back(y),e[y].push_back(x),i++) cin>>x>>y;
dfs(1,0);
for(int i=a[1];i>=0;i--)if(f[1][i])
{
cout<<i;
return 0;
}
}
已经可以通过此题,但是聪明的你发现这个 是可以使用 bitset 优化递推过程的。
bitset 优化实现:
CPPbitset 优化实现:
#include<bits/stdc++.h>
using namespace std;
const int N=1005;
int n,a[N];
bitset<N> f[N];
vector<int> e[N];
void dfs(int x,int fa)
{
if(e[x].size()==1&&x!=1) f[x].set(a[x]);//注意有可能是一条链
f[x].set(0);
for(auto u:e[x])if(u!=fa)
{
dfs(u,x);
vector<bitset<N> > tmp;
for(int i=1;i<=min(a[x],a[u]);i++)if(f[u][i]) tmp.push_back(f[x]<<i);
for(auto y:tmp) f[x]|=y;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1,x,y;i<n;e[x].push_back(y),e[y].push_back(x),i++) cin>>x>>y;
dfs(1,0);
for(int i=a[1];i>=0;i--)if(f[1][i])
{
cout<<i;
return 0;
}
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...