• [bzoj5290][Hnoi2018]道路【树形dp】


    【题目链接】
      https://www.lydsy.com/JudgeOnline/problem.php?id=5290
      https://www.luogu.org/problemnew/show/P4438
    【题解】
      记f[i][j][k]表示现在在i号点从根节点到这个点经过了j条未被修缮的公路和k条未被修缮的铁路的答案。
      于是有:

    f[i][j][k]=min(f[son[0]][j+1][k]+f[son[1]][j][k],f[son[0]][j][k]+f[son[1]][j][k+1])

      son[0]为公路连接的儿子,son[1]为铁路连接的儿子。
      叶子节点的答案直接计算即可,注意在用到的时候再算,否则可能会爆空间。
      最后的答案为f[1][0][0]
      时间复杂度:O(ND2)  D为深度。
      

    # include <bits/stdc++.h>
    # define    N       20010
    # define    T       41
    # define    ll      long long
    # define    inf     0x3f3f3f3f
    using namespace std;
    int read(){
        int tmp=0, fh=1; char ch=getchar();
        while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();}
        while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();}
        return tmp*fh;
    }
    int son[N][2],n;
    ll f[N][T][T],v[N][3];
    ll calc(int x, int i, int j){
        return v[x-n+1][2]*(v[x-n+1][0]+i)*(v[x-n+1][1]+j);
    }
    void dfs(int x, int num0, int num1){
        if (x>=n) return;
        else {
            dfs(son[x][0],num0+1,num1);
            dfs(son[x][1],num0,num1+1);
            for (int i=0; i<=num0; i++)
                for (int j=0; j<=num1; j++){
                    ll tmp00, tmp01, tmp10, tmp11;
                    if (son[x][0]>=n)
                        tmp00=calc(son[x][0],i,j),tmp01=calc(son[x][0],i+1,j);
                        else tmp00=f[son[x][0]][i][j],tmp01=f[son[x][0]][i+1][j];
                    if (son[x][1]>=n)
                        tmp10=calc(son[x][1],i,j),tmp11=calc(son[x][1],i,j+1);
                        else tmp10=f[son[x][1]][i][j],tmp11=f[son[x][1]][i][j+1];
                    f[x][i][j]=min(tmp00+tmp11,tmp01+tmp10);
                }
        }
    }
    int main(){
        n=read();
        for (int i=1; i<n; i++){
            int u=read(), v=read();
            if (u<0) u=-u+(n-1);
            if (v<0) v=-v+(n-1);
            son[i][0]=u;
            son[i][1]=v;
        }
        for (int i=1; i<=n; i++){
            v[i][0]=read();
            v[i][1]=read();
            v[i][2]=read();
        }
        memset(f,inf,sizeof(f));
        dfs(1,0,0);
        printf("%lld
    ",f[1][0][0]);
        return 0;
    }
    
  • 相关阅读:
    node-log4js3.0.6配置
    MySQL命令学习
    64位 windows10,MYSQL8.0.13重置密码(忘记密码或者无法登录)
    64位 windows10,安装配置MYSQL8.0.13
    vscode切换界面布局
    一个网站同时监听两个端口
    javascript +new Date()
    es6 解构
    react列表数据显示
    访问禁止,检测到可疑访问,事件编号
  • 原文地址:https://www.cnblogs.com/Vanisher/p/9135951.html
Copyright © 2020-2023  润新知