• [HNOI/AHOI2018] 道路


    题目链接:https://loj.ac/problem/2510
    题目很长,但是事实上就是有2n-1个点,然后除了叶子节点,每个节点都有左右两条边(需要注意的是这两条边需要区分)。然后给这些边打标记,最后算叶子节点到根节点的没有打标记的左右两种边分别乘上花费的最小值。。。。(呃,我的解释是不是不太清楚。。qwq)

    没有看懂我的解释的还是回去好好看看原题吧qwq看懂题之后我们就可以愉快的做题了。。。

    事实上我被卡空间了。。。。卡在514M也很难过啊qwq。。。

    但是我太蒻了啊。。不会正解啊qwq

    所以我只能放上我的辣鸡代码+思路了。。。

    (f[i][j][k])表示从根节点到节点i有j条公路,k条铁路。

    [f[i][j][k]=min(f[lson(i)][j+1][k]+f[rson(i)][j][k],f[lson(i)][j][k]+f[rson(i)][j][k+1]) ]

    也就是树形DP嘛。。。。上面的转移方程的意思是选取父节点的哪一条边。。。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    #define MAXN 20000
    using namespace std;
    int n;
    int l[MAXN<<1],r[MAXN<<1],a[MAXN<<1],b[MAXN<<1],c[MAXN<<1],len[MAXN<<1];
    long long dp[MAXN<<1][41][41];
    inline void search(int now)
    {
        if(now>=n)
        {
            for(int i=0;i<=40;i++)
                for(int j=0;j<=40;j++)
                    dp[now][i][j]=(long long)c[now]*(a[now]+i)*(b[now]+j);
            return;
        }
        search(l[now]);
        search(r[now]);
        for(int j=0;j<=40;j++)
            for(int k=0;k<=40;k++)
                dp[now][j][k]=min(dp[l[now]][j+1][k]+dp[r[now]][j][k],dp[l[now]][j][k]+dp[r[now]][j][k+1]); 
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&l[i],&r[i]);
            if(l[i]<0) l[i]=abs(l[i])+n-1;
            if(r[i]<0) r[i]=abs(r[i])+n-1;
        //	printf("l=%d r=%d
    ",l[i],r[i]);
        }
        for(int i=0;i<n;i++)
            scanf("%d%d%d",&a[i+n],&b[i+n],&c[i+n]);
        search(1);
        printf("%lld
    ",dp[1][0][0]);
        return 0;
    }
    
  • 相关阅读:
    WebGIS前端地图显示之根据地理范围换算出瓦片行列号的原理(核心) 【系列1-1】
    WMTS服务
    WebGIS 分辨率 比例尺和切片
    Mysql Spatial 空间查询参考
    webapi和传统mvc的context和request的区别
    IIS启动32位运行库
    GEOJSON标准格式学习
    gdal笔记之获取矢量面边界点坐标
    关于TensorFlow,你应该了解的9件事
    C#根据时间范围获取每年每月每周的分组
  • 原文地址:https://www.cnblogs.com/fengxunling/p/9836473.html
Copyright © 2020-2023  润新知