• BZOJ1916[USACO 2010 Open Gold 2.Water Slides]——DP+记忆化搜索


    题目描述

    受到秘鲁的马丘比丘的新式水上乐园的启发,Farmer John决定也为奶牛们建 一个水上乐园。当然,它最大的亮点就是新奇巨大的水上冲浪。超级轨道包含 E (1 <= E <=150,000)条小轨道连接着V (V <= 50,000)个水池,编号为1..V。每个小轨道必须按照特定的方向运行,不能够反向运行。奶牛们从1号水池出发,经过若干条小轨道,最终到达V号水池。每个水池(除了V号和1号之外,都有至少一条小轨道进来和一条小轨道出去,并且,一头奶牛从任何一个水池到达V 号水池。最后,由于这是一个冲浪,从任何一个水池出发都不可能回到这个水池) 每条小轨道从水池P_i到水池Q_i (1 <= P_i <= V; 1<= Q_i <= V; P_i != Q_i), 轨道有一个开心值F_i (0 <= F_i <= 2,000,000,000),Bessie总的开心值就是经过的所有轨道的开心值之和。Bessie自然希望越开心越好,并且,她有足够长的时间在轨道上玩。因此,她精心地挑选路线。但是,由于她是头奶牛,所以,会有至多K (1 <= K <= 10)次的情况,她无法控制,并且随机从某个水池选择了一条轨道(这种情况甚至会在1号水池发生) 如果Bessie选择了在最坏情况下,最大化她的开心值,那么,她在这种情况下一次冲浪可以得到的最大开心值是多少? 在样例中,考虑一个超级轨道,包含了3个水池(在图中用括号表示)和4条小轨道,K的值为1 (开心值在括号外表示出来,用箭头标识)  她总是从1号水池出发,抵达3号水池。如果她总是可以自己选择,就是不会发生不能控制的情况她可以选择从1到2(这条轨道开心值为5),再从2到3(开心值为5),总的开心值为5+5=10。但是,如过她在1号水池失去控制,直接到了3,那么开心值为9,如果她在2号水池失去控制,她总的开心值为8。Bessie想要找到最大化开心值的方案,可以直接从1到3,这样,如果在1号水池失去控制,这样,她就不会在2号水池失去控制了,就能够得到10的开心值。因此,她的开心值至少为9

    输入

    * 第一行: 三个用空格隔开的整数: V, E, 和 K * 第2到第E+1行: 第i+1行包含三个用空格隔开的整数: P_i, Q_i, and F_i

    输出

    * 第一样: 一行一个整数表示在最坏情况下最大化的开心值

    样例输入

    3 4 1
    2 3 5
    1 2 5
    1 3 9
    2 3 3

    样例输出

    9
     
    首先说一下问题的意思:“在最坏情况下最大化的开心值”就是指你想使她的开心值最小,但她想使开心值最大的最优策略。但你想阻止她的方法只有在k个节点阻止她走最长路方向,却不能指定她走哪条路。对于样例,最长路是从1到2再到3,长度为5+5=10。如果你在1节点阻止她,那她只能直接走到3,长度为9;如果你在2阻止她,并不是说她走到2再被阻止,走了长度为3的路,而是直接放弃走2,直接走到3,长度还是9。所以她至少获得的开心值是9。从1走到n等价于从n走到1,所以我们不妨倒着来做(正推比较麻烦但也可行),定义f[i][j]表示走到i节点还剩j次失误的最优解,最终结果就是f[1][0];f[x][j]=min(max(f[from[i]][j]+val[i]),min(f[from[i]][j-1]+val[i])),其中from[i]表示能直接到达x的一个点。从1节点记忆化搜索即可。
    最后附上代码。
    #include<queue>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int head[50010];
    int to[150010];
    int next[150010];
    long long val[150010];
    int n,m,k;
    int x,y;
    long long v;
    int tot;
    long long f[50010][16];
    long long INF=1ll<<60;
    void add(int x,int y,long long v)
    {
        tot++;
        next[tot]=head[x];
        head[x]=tot;
        to[tot]=y;
        val[tot]=v;
    }
    long long dfs(int x,int y)
    {
        if(f[x][y]!=INF)
        {
            return f[x][y];
        }
        long long ma=0ll;
        long long mi=INF;
        for(int i=head[x];i;i=next[i])
        {
            ma=max(ma,dfs(to[i],y)+val[i]);
            if(y+1<=k)
            {
                mi=min(mi,dfs(to[i],y+1)+val[i]);
            }
        }
        return f[x][y]=min(mi,ma);
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%lld",&x,&y,&v);
            add(x,y,v);
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<=k;j++)
            {
                if(i!=n)
                {
                    f[i][j]=INF;
                }
                else
                {
                    f[i][j]=0;
                }
            } 
        }
        printf("%lld",dfs(1,0));
    }
  • 相关阅读:
    phpstorm 2017 关掉变量提示 parameter name hints,改变打开方式
    RMAN-06496: must use the TO clause when the database is mounted or open
    FAL[client]: Failed to request gap sequence GAP
    搭建rac对单实例的MAA
    Linux下安装Oracle 10g(redhat 4)
    ora-01031:insufficient privileges
    ORA-12514: TNS:listener does not currently know of service requested in connect descriptor
    checking for oracle home incompatibilities failed
    用root帐号切换其他帐号提示 su: warning: cannot change directory to /home/oracle: Permission denied
    an error occured during the file system check
  • 原文地址:https://www.cnblogs.com/Khada-Jhin/p/9135527.html
Copyright © 2020-2023  润新知