CF1988D The Omnipotent Monster Killer*2000树形dp
\[\begin{flalign*}
&题意:给定一棵带点权的树,每轮游戏开始会受到所有未删除节点权值和的伤害\\&
结束时可以删除任意个不相邻的节点,问删完所有点时收到的最小伤害和&\\&
\\&
定义dp_{i,j}为第j轮删除i节点,子树i所产生的最小伤害\\&
初值为j*a_i,转移方程:f_{i,j}=f_{i,j}+\sum ^{}_{k!=j}min(f_{son_i,k})\\&
复杂度:O(N*颜色数上界)\\&
下面证明颜色数上界不超过logN\\&
考虑从叶子往上推,那么点i的颜色最小值为mex(color_{son_i})(此处主要指的是种类数)\\&
设f(T)为颜色数上界为T的最小子树大小\\&
那么有递推式:f(T)=1+\sum^{T-1}_{i=0}f(i),根据f(0)=1,可以推出:f(N)=2^N\\&
从而大小为N的树的颜色上界为log_2N
\end{flalign*}
\]
const int N=3e5+10;
int a[N];
void solve(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
vector<vector<int>>g(n+1),dp(n+1,vector<int>(24));
vector<int>pre,suf;
for(int i=1;i<n;i++){
int u,v; cin>>u>>v;
g[u].push_back(v),g[v].push_back(u);
}
auto dfs=[&](auto self,int u,int fa)->void{
for(int i=1;i<20;i++) dp[u][i]=i*a[u];
dp[u][0]=dp[u][20]=1e18;
for(auto v:g[u]){
if(v==fa) continue;
self(self,v,u);
for(int i=1;i<20;i++){
dp[u][i]+=min(pre[i-1],suf[i+1]);
}
}
pre=suf=dp[u];
for(int i=1;i<20;i++){
pre[i]=min(pre[i-1],dp[u][i]);
}
for(int i=19;i>=1;i--){
suf[i]=min(suf[i+1],dp[u][i]);
}
};
dfs(dfs,1,0);
int ans=1e18;
for(int i=1;i<20;i++) ans=min(ans,dp[1][i]);
cout<<ans<<endl;
}

浙公网安备 33010602011771号