博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CF277D Google Code Jam
阅读量:4568 次
发布时间:2019-06-08

本文共 2185 字,大约阅读时间需要 7 分钟。

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

\(n\leq1000;t,\ TimeSmall_i,\ TimeLarge_i\in[1,\ 1560];\ ScoreSmall_i,\ ScoreLarge_i\in[1,\ 10^9];\ 0\leq ProbFail_i\leq 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\times p_i/(1-p_i)>t_j\times p_j/(1-p_j)\)

按照这个规则排序即可。

代码

#include 
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;}

转载于:https://www.cnblogs.com/Juanzhang/p/11334597.html

你可能感兴趣的文章
MySQL的binlog日志
查看>>
vagrant The specified host network collides with a non-hostonly network!
查看>>
0x59 单调队列优化DP
查看>>
mysql中的union用法
查看>>
利用python爬取龙虎榜数据及后续分析
查看>>
Python 常用的方法
查看>>
Git和GitHub使用总结
查看>>
php array_multisort对数据库结果多个字段进行排序
查看>>
关于大型网站技术演进的思考(十六)--网站静态化处理—前后端分离—下(8)...
查看>>
Python中dict详解
查看>>
[LeetCode][JavaScript]House Robber
查看>>
java经典算法四十题
查看>>
(转载) MTK flash
查看>>
Python 序列化之json、pickle
查看>>
python3 多线程笔记
查看>>
无尽的控件-GridView复合表头
查看>>
Luogu4726 【模板】多项式指数函数(NTT+多项式求逆)
查看>>
e3mall商城的归纳总结2之认识dubbo、zookeeper
查看>>
纯js实现图片上传
查看>>
嵌入式SQL
查看>>