• 【Luogu】P2015二叉苹果树(DP,DFS)


    题目链接

    设f[i][j][k]表示给以i为根节点的子树分配j条可保留的树枝名额的时候,状态为k时能保留的最多苹果。
    k有三种情况。
    k=1:我只考虑子树的左叉,不考虑子树的右叉,此时子树能保留的最多的苹果。
    k=2:我只考虑子树的右叉,不考虑子树的左叉,此时子树能保留的最多的苹果。
    k=3:我既考虑子树的左叉,又考虑子树的右叉,此时子树能保留的最多的苹果。
    这样状态转移方程就出来了。
    f[i][j][1]=max(f[i][j][1],f[leftson[i]][j-1][3]+val[i][leftson[i]])
    f[i][j][2]=max(f[i][j][2],f[rightson[i]][j-1][3]+val[i][rightson[i]])
    f[i][j][3]=max(f[i][j][3],f[i][v][1]+f[i][j-v][2]) 其中v从0到j枚举。
    最后f[1][q][3]就是最终的答案。
    注意记忆化搜索。我因为这个T了四次。

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    inline long long read(){
        long long num=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')    f=-1;
            ch=getchar();
        }
        while(isdigit(ch)){
            num=num*10+ch-'0';
            ch=getchar();
        }
        return num*f;
    }
    
    struct Edge{
        int next,to,val;
    }edge[100010];
    int head[100010],num;
    int father[100010];
    int size[100010];
    inline void add(int from,int to,int val){
        edge[++num]=(Edge){head[from],to,val};
        head[from]=num;
    }
    
    void find(int x,int fa){
        father[x]=fa;
        size[x]=1;
        for(int i=head[x];i;i=edge[i].next){
            int to=edge[i].to;
            if(to!=fa){
                find(to,x);
                size[x]+=size[to];
            }
        }
    }
    
    int f[103][103][4];
    
    void dfs(int x,int s){
        if(size[x]==1||f[x][s][3])    return;
        int cnt=0;
        for(int i=head[x];i;i=edge[i].next){
            int to=edge[i].to;
            if(to==father[x])    continue;
            cnt++;
            for(int v=0;v<size[to]&&v<s;++v){
                dfs(to,v);
                f[x][v+1][cnt]=f[to][v][3]+edge[i].val;
            }
        }
        for(int v=0;v<=s;++v)
            f[x][s][3]=max(f[x][s][3],f[x][v][1]+f[x][s-v][2]);
        return;
    }
    
    int main(){
        int n=read(),q=read();
        for(int i=1;i<n;++i){
            int from=read(),to=read(),val=read();
            add(from,to,val);
            add(to,from,val);
        }
        find(1,1);
        dfs(1,q);
        printf("%d",f[1][q][3]);
        return 0;
    }
  • 相关阅读:
    SpringBoot-redis-session
    设计模式总结
    linux 查看磁盘信息
    MAC配置JAVA环境变量
    mysql设计规范二
    mysql设计规范一
    Alibaba 镜像
    ELK之Logstash配置文件详解
    Docker 搭建 ELK 读取微服务项目的日志文件
    SpringBoot 读取配置文件的值 赋给静态变量
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/7573779.html
Copyright © 2020-2023  润新知