BZOJ 4557: [JLoi2016]侦察守卫 树形DP

本文深入探讨了树形DP算法的实现细节,通过定义状态$f[x][j]$和$g[x][j]$来解决树状结构上的动态规划问题。文章详细讲解了状态转移方程,包括如何处理边界条件,以及在递归过程中如何有效地更新状态。

状态还比较自然. 

令 $f[x][j]$ 表示 $x$ 的子树全被控制,且多出来 $j$ 层. 

令 $g[x][j]$ 表示还需要 $j$ 层才能控制 $x$ 所有子树.     

转移 $f[x][j]$ 的时候有两种情况:之前已经控制:$f[x][j]+g[y][j]$,之前没控制:$g[x][j+1]+f[y][j+1]$.   

注意一下转移边界就好了. 

#include <cstdio> 
#include <string> 
#include <cstring> 
#include <algorithm>    
#define N 500002   
#define inf 1000000000   
using namespace std;   
void setIO(string s) 
{
    string in=s+".in"; 
    string out=s+".out"; 
    freopen(in.c_str(),"r",stdin); 
    // freopen(out.c_str(),"w",stdout); 
}    
int D,n,edges;
int f[N][21],g[N][21],v[N],vis[N],hd[N],to[N<<1],nex[N<<1];   
void add(int u,int v) 
{
    nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;  
}
void dfs(int x,int ff) 
{   
    if(vis[x]) f[x][0]=g[x][0]=v[x];    
    int i,j; 
    for(i=1;i<=D;++i)   f[x][i]=v[x];  
    f[x][D+1]=inf;       
    for(i=hd[x];i;i=nex[i]) if(to[i]!=ff) 
    {
        int y=to[i];          
        dfs(y,x);                 
        for(j=0;j<=D;++j) 
            f[x][j]=min(f[x][j]+g[y][j],f[y][j+1]+g[x][j+1]);        
        for(j=D;j>=0;--j) f[x][j]=min(f[x][j],f[x][j+1]);    
        g[x][0]=f[x][0];
        for(j=1;j<=D;++j) g[x][j]+=g[y][j-1];    
        for(j=1;j<=D;++j) g[x][j]=min(g[x][j],g[x][j-1]); 
    }
}
int main() 
{ 
    // setIO("input");      
    int i,j,m; 
    scanf("%d%d",&n,&D);           
    for(i=1;i<=n;++i) scanf("%d",&v[i]);   
    scanf("%d",&m); 
    for(i=1;i<=m;++i) 
    {
        int x; 
        scanf("%d",&x),vis[x]=1; 
    }          
    for(i=1;i<n;++i) 
    {
        int x,y;                  
        scanf("%d%d",&x,&y),add(x,y),add(y,x); 
    }    
    dfs(1,0);    
    printf("%d\n",g[1][0]);  
    return 0; 
}

  

根据原作 https://pan.quark.cn/s/459657bcfd45 的源码改编 Classic-ML-Methods-Algo 引言 建立这个项目,是为了梳理和总结传统机器学习(Machine Learning)方法(methods)或者算法(algo),和各位同仁相互学习交流. 现在的深度学习本质上来自于传统的神经网络模型,很大程度上是传统机器学习的延续,同时也在不少时候需要结合传统方法来实现. 任何机器学习方法基本的流程结构都是通用的;使用的评价方法也基本通用;使用的一些数学知识也是通用的. 本文在梳理传统机器学习方法算法的同时也会顺便补充这些流程,数学上的知识以供参考. 机器学习 机器学习是人工智能(Artificial Intelligence)的一个分支,也是实现人工智能最重要的手段.区别于传统的基于规则(rule-based)的算法,机器学习可以从数据中获取知识,从而实现规定的任务[Ian Goodfellow and Yoshua Bengio and Aaron Courville的Deep Learning].这些知识可以分为四种: 总结(summarization) 预测(prediction) 估计(estimation) 假想验证(hypothesis testing) 机器学习主要关心的是预测[Varian在Big Data : New Tricks for Econometrics],预测的可以是连续性的输出变量,分类,聚类或者物品之间的有趣关联. 机器学习分类 根据数据配置(setting,是否有标签,可以是连续的也可以是离散的)和任务目标,我们可以将机器学习方法分为四种: 无监督(unsupervised) 训练数据没有给定...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值