zoukankan      html  css  js  c++  java
  • 洛谷P1809 过河问题 经典贪心问题

    • 作者:zifeiy
    • 标签:贪心

    题目链接:https://www.luogu.org/problem/P1809

    我们假设第 (i) 个人过河的耗时是 (t[i]) ,并且 (t[i]) 按照从小到大进行了排序(即: (t[i] le t[i+1]) ), 并且设状态 (f[i]) 表示前 (i) 个人过河的最小花费。
    此处我们的贪心基于这样一种思想:优先令 (t[i]) 大的过河。
    那么:
    (i = 1) 时,只有一个人,所以此时 (f[1] = t[1])
    (i = 2) 时,只有两个人,所以此时 (f[2] = t[2])
    (i = 3) 时,我们可以选择第1个人陪第2个人过去,再回来接第3个人;或者第1个人陪第3个人过去,再回来接第2个人,两种情况下都满足 (f[3] = t[2] + t[1] + t[3])
    (i gt 3) 时,我们要送走第 (i) 个人,有两种方式:

    • 方式一:第1个人和第i个人过河,第1个人再回来,此时 (f[i] = f[i-1] + t[i] + t[1])
    • 方式二:第1个人和第2个人过河,第2个人再回来,第i-1个人和第i个人过来,第1个人再回来(或者:第1个人和第2个人过河,第1个人再回来,第i-1个人和第i个人多来,第2个人再回来),此时状态变化到了 (f[i-2]) ,此时 (f[i] = f[i-2] + t[2] + t[2] + t[i] + t[1])

    所以,当 (i gt 3) 时, (f[i] = max(f[i-1] + t[i] + t[1] , f[i-2] + t[2] + t[2] + t[i] + t[1]))

    其实我们可以发现,对于任意一个 (f[i]) ,它的状态都是由 (f[j] (j gt i)) 演变过来的,但是我们可以通过先求解 (f[i]) ,推导出 (f[j]) ,最终获得我们的答案—— (f[n])

    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 100010;
    int n, t[maxn], f[maxn];
    int main() {
        cin >> n;
        for (int i = 1; i <= n; i ++) cin >> t[i];
        sort(t+1, t+1+n);
        for (int i = 1; i <= n; i ++) {
            if (i == 1) f[i] = t[i];
            else if (i == 2) f[i] = t[2];
            else if (i == 3) f[i] = t[2] + t[1] + t[3];
            else f[i] = min(f[i-1]+t[i]+t[1], f[i-2]+t[2]+t[2]+t[i]+t[1]);
        }
        cout << f[n] << endl;
        return 0;
    }
    
  • 相关阅读:
    基于微信小程序的票价和时间选择以及计算总价
    基于Echarts的股票K线图展示
    基于Echarts的中国地图数据展示
    微信公众号网页授权登录获取用户基本信息
    springboot+mybatis+maven角色权限框架
    java服务端微信小程序支付
    推理 —— 猜帽子颜色
    Java 容器的使用及数组、List、Set 的相互转换
    构建工具 —— Groovy 与 Gradle
    效率生产力工具 —— idea 插件
  • 原文地址:https://www.cnblogs.com/codedecision/p/11654504.html
Copyright © 2011-2022 走看看