• CF277D Google Code Jam


    CF277D Google Code Jam

    (n) 道题目,每道题分为小题目和大题目,只有做完了小题目才能做大题目,提交结果会在比赛结束后得知。其中,做第 (i) 个小题目需要 (ScoreSmall_i) 分钟,可以获得得分 (TimeSmall_i) ;做第 (i) 个大题目需要 (ScoreLarge_i) 分钟,可以获得得分 (TimeLarge_i) 。每个小题目可以一遍过,第 (i) 个大题目有 (ProbFail_i) 的几率错误,总罚时是 最后一次正确提交的时间。现在你有 (t) 分钟,求在这 (t) 分钟内你最多期望能够获得多少分,并且在满足得分最多的情况下使得罚时最小。

    (nleq1000;t, TimeSmall_i, TimeLarge_iin[1, 1560]; ScoreSmall_i, ScoreLarge_iin[1, 10^9]; 0leq ProbFail_ileq 1)

    dp,贪心,概率


    背包可以解决最高得分,那么现在要找到一种最优的顺序使得罚时最低。

    可以发现 (Small) 对罚时没有特殊影响,可以直接计算。假设需要解决两道题 (i, j)(Large) ,令 (t_i=TimeLarge_i, p_i=ProbFail_i),若 (i) 排在 (j) 之前,罚时为 ((1-p_j)(t_i+t_j)+t_i(1-p_i)p_j)

    化式子得,若 (i) 排在 (j) 之前的得分大于 (j) 排在 (i) 之前当且仅当 (t_i imes p_i/(1-p_i)>t_j imes p_j/(1-p_j))

    按照这个规则排序即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long double db;
    const db eps = 1e-15;
    const int maxn = 2010;
    int n, m;
    db dp[maxn], val[maxn];
    
    struct node {
      int v1, v2, t1, t2; db p;
      
      inline bool operator < (const node &o) const {
        return t2 * p / (1 - p) < o.t2 * o.p / (1 - o.p);
      }
    } a[maxn];
    
    int main() {
      scanf("%d %d", &n, &m);
      for (int i = 1; i <= n; i++) {
        double f;
        scanf("%d %d %d %d %lf", &a[i].v1, &a[i].v2, &a[i].t1, &a[i].t2, &f);
        a[i].p = f;
      }
      sort(a + 1, a + n + 1);
      for (int i = 1; i <= m; i++) {
        dp[i] = -1e18, val[i] = 1e18;
      }
      for (int i = 1; i <= n; i++) {
        db p = a[i].p, tmp1, tmp2;
        int v1 = a[i].v1, v2 = a[i].v2;
        int t1 = a[i].t1, t2 = a[i].t2;
        for (int j = m; j >= t1; j--) {
          tmp1 = dp[j - t1] + v1, tmp2 = val[j - t1] + t1;
          if (dp[j] < tmp1 || (fabs(dp[j] - tmp1) < eps && val[j] > tmp2)) {
            dp[j] = tmp1, val[j] = tmp2;
          }
          if (j < t1 + t2) continue;
          tmp2 = dp[j - t1 - t2] + v1 + (1 - p) * v2;
          tmp1 = t1 + (1 - p) * (j - t1) + p * val[j - t1 - t2];
          if (dp[j] < tmp2 || (fabs(dp[j] - tmp2) < eps && val[j] > tmp1)) {
            dp[j] = tmp2, val[j] = tmp1;
          }
        }
      }
      int pos = 0;
      for (int i = 1; i <= m; i++) {
        if (dp[pos] < dp[i] || (fabs(dp[pos] - dp[i]) < eps && val[i] < val[pos])) {
          pos = i;
        }
      }
      printf("%.10lf %.10lf", (double) dp[pos], (double) val[pos]);
      return 0;
    }
    
  • 相关阅读:
    Selenium2+python自动化-查看selenium API
    彻底搞懂scrapy的中间件第二章
    彻底搞懂scrapy的中间件第一章
    爬虫面试题
    爬取58同城二手房数据存储到redis数据库和mysql数据库
    Scrapy操作浏览器获取网易新闻数据
    Scrapy框架中的 UA伪装
    scrapy框架中如何使用selenuim
    基于scrapy中---全站爬取数据----CrawlSpider的使用
    基于百度AI的自然语言处理文字分类
  • 原文地址:https://www.cnblogs.com/Juanzhang/p/11334597.html
Copyright © 2020-2023  润新知