• bzoj 5290: [Hnoi2018]道路


    Description

    Solution

    PJDP毁青春
    注意到性质:到根的道路不超过 (40)
    所以我们只关系一个点上面的道路的情况就行了
    (f[x][i][j]) 表示一个点 (x) ,上面有 (i) 条公路没修,(j) 条铁路没修的最小代价
    (f[x][i][j]=min(f[ls][i+1][j]+f[rs][i][j],f[ls][i][j]+f[rs][i][j+1]))

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<ctime>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const int N=40010;
    int n,ls[N],rs[N],b[N][2];
    ll A[N],B[N],C[N],f[20010][45][45];
    int xl[N],yl[N],tn;
    inline void DFS(int x,int X,int Y){
      xl[x]=X;yl[x]=Y;
      if(x>=n)return ;
      DFS(ls[x],X+1,Y);
      DFS(rs[x],X,Y+1);
    }
    inline ll F(int x,int i,int j){
      if(x<n)return f[x][i][j];
      return C[x]*(A[x]+i)*(B[x]+j);
    }
    inline void dfs(int x){
      if(x>=n)return ;
      dfs(ls[x]);dfs(rs[x]);
      for(int i=0;i<=xl[x];i++)
        for(int j=0;j<=yl[x];j++)
          f[x][i][j]=min(F(ls[x],i+1,j)+F(rs[x],i,j),F(ls[x],i,j)+F(rs[x],i,j+1));
    }
    int main(){
      scanf("%d",&n);tn=n+n-1;
      for(int i=1;i<n;i++){
        scanf("%d%d",&b[i][0],&b[i][1]);
        if(b[i][0]<0)b[i][0]=-b[i][0]+n-1;
        if(b[i][1]<0)b[i][1]=-b[i][1]+n-1;
        ls[i]=b[i][0];rs[i]=b[i][1];
      }
      for(int i=1;i<=n;i++)cin>>A[i+n-1]>>B[i+n-1]>>C[i+n-1];
      DFS(1,0,0);
      memset(f,127/3,sizeof(f));
      dfs(1);
      cout<<f[1][0][0]<<endl;
      return 0;
    }
    
    
  • 相关阅读:
    redis对string进行的相关操作
    bs4解析库
    redis对键进行的相关操作
    python常见的函数和类方法
    一些(也许)有用的技巧以及注意事项
    【复健内容】NOIP2020 题解
    类欧几里得的一个方法
    UOJ Round #12
    Goodbye Yiwei
    UOJ Round #11
  • 原文地址:https://www.cnblogs.com/Yuzao/p/8856773.html
Copyright © 2020-2023  润新知