zoukankan      html  css  js  c++  java
  • BZOJ 1916 [Usaco2010 Open]冲浪

    BZOJ_1916

        对于这种题目,我向来是很头晕的,不过按dp的套路来的话还是可以解决的。

        不妨用dp[i][j]表示在第i个点时,已经失控了j次,至少能得到的开心值。我们不妨只讨论j<K的情况,这时一共有两种选择,要么被失控,要么能主动选择。如果能主动选择的话,肯定会选接下来至少能得到的开心值最大的决策,而被失控的话,就要考虑至少能得到的开心值最小的决策了。最后再综合二者取最小值就是当前状态下至少能得到的开心值,写成状态转移方程就是dp[i][j]=min{max{dp[k][j] + w[i][k]},min{dp[k][j+1] + w[i][k]}},其中w[i][k]表示i到k这条边的开心值。

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define MAXD 50010
    #define MAXM 150010
    #define INF 0x3f3f3f3f3f3f3f3fll
    typedef long long LL;
    int N, M, K, first[MAXD], e, next[MAXM], v[MAXM];
    LL w[MAXM], dp[MAXD][11];
    void add(int x, int y, int z)
    {
        v[e] = y, w[e] = z;
        next[e] = first[x], first[x] = e ++;
    }
    void init()
    {
        memset(first, -1, sizeof(first[0]) * (N + 1)), e = 0;
        for(int i = 0; i < M; i ++)
        {
            int x, y, z;
            scanf("%d%d%d", &x, &y, &z);
            add(x, y, z);
        }
    }
    LL dfs(int i, int j)
    {
        if(dp[i][j] != INF) return dp[i][j];
        LL ans = 0, min = INF;
        for(int t = first[i]; t != -1; t = next[t])
        {
            ans = std::max(ans, dfs(v[t], j)) + w[t];
            if(j < K) min = std::min(min, dfs(v[t], j + 1) + w[t]);
        }
        ans = std::min(ans, min);
        return dp[i][j] = ans;
    }
    void solve()
    {
        memset(dp, 0x3f, sizeof(dp[0]) * (N + 1));
        memset(dp[N], 0, sizeof(dp[N]));
        printf("%lld\n", dfs(1, 0));
    }
    int main()
    {
        while(scanf("%d%d%d", &N, &M, &K) == 3)
        {
            init();
            solve();
        }
        return 0;
    }
  • 相关阅读:
    【Python学习笔记之三】lambda表达式用法小结
    Cisco Packet Tracer 6.0 实验笔记
    Kali Linux 下安装中文版输入法
    kali 2018.1安装教程
    Kali Linux菜单中各工具功能大全
    互联网电商购物车架构演变案例
    互联网业务场景下消息队列架构
    物流系统高可用架构案例
    高并发下海量容器案例一
    客服系统微服务架构的演化
  • 原文地址:https://www.cnblogs.com/staginner/p/2727662.html
Copyright © 2011-2022 走看看