1 条题解

  • 0
    @ 2025-8-24 21:44:10

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar fdfdf
    这个家伙不懒,但还是什么都没有留下

    搬运于2025-08-24 21:44:10,当前版本为作者最后更新于2018-01-01 15:15:53,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    本人表示一开始看到这道题的时候并没有看懂

    比如这句

    如果Bessie选择了在最坏情况下,最大化她的开心值,那么,她在这种情况下一次冲浪可以得到的最大开心值是多少?

    机房大佬给出的解答是:

    假设你有意想让Bessie的愉悦值最小,题目规定你只能改k条边,在你们双方都做出最优决策的情况下,所能得到的愉悦值是多少?

    我想这不是博弈论吗(惊吓)

    其实并不是很复杂

    双方最优的意思大概就是:如果其中一方的操作不符合这个步骤,那么另一方总可以通过一些步骤,使得结果更加偏向自己的一方

    似乎有种命中注定的感觉

    接下来开始解题吧

    状态设为f[k][i]f[k][i](0≤k≤K),

    表示Bessie从i号节点出发,在k次失误下能够得到的最优值

    因为Bessie一定会冲到n号节点,所以我们f[0][n]=0f[0][n]=0作为开始状态

    考虑f[k][i]f[k][i]的转移,当前只可能有两种决策:

    1.Bessie选择最优决策:此时它应该是从f[k][v]f[k][v](v为以u开始的边指向的结点)中选择一个最大值,然后选择那个方向;如果它不选择那个方向的话,我们就可以通过之后的k次修改使得它达不到比当前更大的愉悦值;即a=max(f[k][v])a=max({f[k][v]})

    2.我们选择最优决策(即让Bessie走向愉悦值最小的道路),那么我们肯定会从

    f[k-1]v中选择一个最小值,然后让Bessie走上那条不归路...即if(k>0)b=min(f[k1][v])if(k>0)b=min({f[k-1][v]})

    这两种决策的结果应该取最小值,因为我们可以选择从什么时候让BEssis滑稽w

    f[k][u]=min(a,b)f[k][u]=min(a,b)

    最后答案在f[K][1]f[K][1]

    最后注意开long long

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #define RG register
    using namespace std;
    typedef long long ll;
    const int N=50010;
    const int M=150010;
    const ll inf=((1ll*1)<<60);
    ll n,m,k;
    ll head[N],to[M],nxt[M],val[M],cnt;
    ll f[11][N];
    ll d[N],x[N];
    bool vis[N];
    queue<ll>Q;
    inline void add(ll u,ll v,ll w){
        to[++cnt]=v;
        val[cnt]=w;
        nxt[cnt]=head[u];
        head[u]=cnt;
    }
    
    ll dfs_memory(ll u,ll s){//记忆化搜索(正推公式太过复杂)
        if(u==n)return 0;
        if(f[s][u])return f[s][u];
        RG ll maxn=0,minn=inf,v;
        for(RG int i=head[u];i;i=nxt[i]){//第一种情况
            v=to[i];
            maxn=max(maxn,dfs_memory(v,s)+val[i]);
        }
        if(s)
            for(RG int i=head[u];i;i=nxt[i]){//第二种情况
                v=to[i];
                minn=min(minn,dfs_memory(v,s-1)+val[i]);
            }
        if(!s)f[s][u]=maxn;
        else f[s][u]=min(maxn,minn);
        //printf("f[%d][%d]=%d\n",s,u,f[s][u]);
        return f[s][u];
    }
    
    int main()
    {
        scanf("%lld%lld%lld",&n,&m,&k);
        for(RG ll i=1,u,v,w;i<=m;i++){
            scanf("%lld%lld%lld",&u,&v,&w);
            add(u,v,w);
        }
        printf("%lld\n",dfs_memory(1,k));
        return 0;
    }
    
    • 1

    信息

    ID
    2056
    时间
    1000ms
    内存
    125MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者