Codeforces 101623E English Restaurant - 动态规划
题目传送门
题目大意
餐厅有$n$张桌子,第$i$张桌子可以容纳$c_i$个人,有$t$组客人,每组客人的人数等概率是$[1, g]$中的整数。
每来一组人数为$x$客人,餐厅如果能找到最小的$c_j$使得$c_j \geqslant x$,那么就会把这张桌子分配给这些客人,并得到$x$的收益。
问期望的收益。
好像可以枚举每一种人数,然后算一下,但时间复杂度很爆炸。
先添加若干个容量为$\infty$的桌子。这样每组人一定能够分配到一张桌子,只是可能没有收益。
考虑最后答案一定是将桌子排序后,若干段连续的桌子被占用。
用$f_{l, r}$表示恰好$[l, r]$这段桌子被占用的所有方案的收益总和和方案数。每次转移考虑枚举最后一组人来的时候占用的桌子,假如它是$mid$,那么最后一组人可行的人数是$(c_{l - 1}, c_{mid}]$。
然后做一个背包,$h_{i, j}$表示考虑到在时刻$i$及其之后来的人,被占用的最靠左的左端点是$j$,所有方案的收益总和和方案数。转移的时候枚举这一段的长度,以及前一段的区间的左端点,注意两个区间不能相交。后者用一个后缀和优化掉。
注意每组人是带标号的,所以合并两个方案的时候还需要分配标号。
Code
- /**
- * Codeforces
- * Gym#101623E
- * Accepted
- * Time: 46ms
- * Memory: 2600k
- */
- #include <algorithm>
- #include <iostream>
- #include <cstdlib>
- #include <cstdio>
- #include <vector>
- using namespace std;
- typedef bool boolean;
- typedef long double ld;
- typedef pair<ld, ld> pdd;
- pdd operator + (const pdd& a, const pdd& b) {
- return pdd(a.first + b.first, a.second + b.second);
- }
- pdd operator * (const pdd& a, const pdd& b) {
- return pdd(a.first * b.second + a.second * b.first, a.second * b.second);
- }
- pdd operator * (const pdd& a, ld x) {
- return pdd(a.first * x, a.second * x);
- }
- ld nature_sum(int x) {
- return x * (x + ) >> ;
- }
- const int N = ;
- int n, g, t;
- vector<int> c;
- ld C[N << ][N << ];
- pdd f[N << ][N << ], h[N][N << ], s[N][N << ];
- inline void init() {
- scanf("%d%d%d", &n, &g, &t);
- c.resize(n);
- for (int i = ; i < n; i++) {
- scanf("%d", &c[i]);
- c[i] = min(c[i], g);
- }
- for (int i = ; i < t; i++)
- c.push_back(g + );
- sort(c.begin(), c.end());
- n = c.size();
- }
- inline void solve() {
- C[][] = ;
- for (int i = ; i <= n; i++) {
- C[i][] = C[i][i] = ;
- for (int j = ; j < i; j++)
- C[i][j] = C[i - ][j] + C[i - ][j - ];
- }
- for (int r = ; r < n; r++)
- for (int l = r; ~l; l--) {
- for (int mid = l; mid <= r; mid++) {
- pdd val; //(0, 1);//C[r - l][r - mid]);
- if (c[mid] > g)
- val = pdd(, g - ((l) ? (min(c[l - ], g)) : ()));
- else
- val = pdd(nature_sum(c[mid]) - ((l) ? (nature_sum(c[l - ])) : ()), c[mid] - ((l) ? (c[l - ]) : ()));
- pdd vall = (mid > l) ? (f[l][mid - ] * C[r - l][r - mid]) : (pdd(, ));
- pdd valr = (mid < r) ? (f[mid + ][r]) : (pdd(, ));
- f[l][r] = f[l][r] + (vall * val * valr);
- }
- // cerr << l << " " << r << " " << f[l][r].first << " " << f[l][r].second << '\n';
- }
- for (int i = ; i < t; i++)
- for (int j = ; j < n - t + i + ; j++)
- h[i][j] = f[j][j + t - i - ];
- for (int i = t; i--; ) {
- int all = t - i;
- for (int j = ; j + all < n; j++) {
- for (int k = i + ; k < t; k++) {
- int put = k - i;
- // cerr << i << " " << j << " " << k << " " << all << " " << put << '\n';
- ld comb = C[all][put];
- h[i][j] = h[i][j] + (f[j][j + put - ] * comb * s[k][j + put + ]);
- }
- // cerr << i << " " << j << " " << h[i][j].first << " " << h[i][j].second << '\n';
- }
- s[i][n - ] = h[i][n - ];
- for (int j = n - ; j >= ; j--)
- s[i][j] = s[i][j + ] + h[i][j];
- }
- pdd ans(, );
- for (int i = ; i < n; i++)
- ans = ans + h[][i];
- // cout << (ans.first / ans.second) << '\n';
- double E = ans.first / ans.second;
- printf("%.9lf", E);
- }
- int main() {
- init();
- solve();
- return ;
- }
Codeforces 101623E English Restaurant - 动态规划的更多相关文章
- Codeforces 839C Journey - 树形动态规划 - 数学期望
There are n cities and n - 1 roads in the Seven Kingdoms, each road connects two cities and we can r ...
- Codeforces 834D The Bakery - 动态规划 - 线段树
Some time ago Slastyona the Sweetmaid decided to open her own bakery! She bought required ingredient ...
- Codeforces 837D Round Subset - 动态规划 - 数论
Let's call the roundness of the number the number of zeros to which it ends. You have an array of n ...
- CodeForces 623E Transforming Sequence 动态规划 倍增 多项式 FFT 组合数学
原文链接http://www.cnblogs.com/zhouzhendong/p/8848990.html 题目传送门 - CodeForces 623E 题意 给定$n,k$. 让你构造序列$a( ...
- Codeforces 264C Choosing Balls 动态规划
原文链接https://www.cnblogs.com/zhouzhendong/p/CF264C.html 题目传送门 - CF264C 题意 给定一个有 $n$ 个元素的序列,序列的每一个元素是个 ...
- Codeforces 1000G Two-Paths 树形动态规划 LCA
原文链接https://www.cnblogs.com/zhouzhendong/p/9246484.html 题目传送门 - Codeforces 1000G Two-Paths 题意 给定一棵有 ...
- codeforces 17C Balance(动态规划)
codeforces 17C Balance 题意 给定一个串,字符集{'a', 'b', 'c'},操作是:选定相邻的两个字符,把其中一个变成另一个.可以做0次或者多次,问最后可以生成多少种,使得任 ...
- Codeforces 762D Maximum path 动态规划
Codeforces 762D 题目大意: 给定一个\(3*n(n \leq 10^5)\)的矩形,从左上角出发到右下角,规定每个格子只能经过一遍.经过一个格子会获得格子中的权值.每个格子的权值\(a ...
- CF思维联系–CodeForces - 225C. Barcode(二路动态规划)
ACM思维题训练集合 Desciption You've got an n × m pixel picture. Each pixel can be white or black. Your task ...
随机推荐
- lua 操作redis
Redis在2.6推出了脚本功能,允许开发者使用Lua语言编写脚本传到Redis中执行.使用脚本的好处如下: 1.减少网络开销:本来5次网络请求的操作,可以用一个请求完成,原先5次请求的逻辑放在red ...
- express 随笔
#express 1.使用Express 应用生成器 npm install express-generator -g 2.创建一个命名为 myapp 的应用 express myapp 3.安装所有 ...
- Python reverse()方法--list
描述 reverse()方法:用于反转列表元素的排列顺序. 语法 语法格式:list.reverse() 参数 NA 返回值 无返回值 实例 #!/usr/bin/python3 a = ['abc' ...
- js实现图片变化
CSS .home{ position: relative; width: 100%; height: 900px; overflow: hidden; } .home #tup{ position: ...
- check failed status == cudnn_status_success (4 vs. 0) cudnn_status_internal_error
Check failed: error == cudaSuccess (30 vs. 0) unknown error 这个有可能是显存不足造成的,或者网络参数不对造成的 check failed ...
- 常用数据类型的方法--str、int、list、dict
一.字符串类型(str) class str(basestring): """ str(object='') -> string Return a nice str ...
- Spring框架学习之--搭建spring框架
此文介绍搭建一个最最简单的spring框架的步骤 一.创建一个maven项目 二.在pom.xml文件中添加依赖导入spring框架运行需要的相关jar包 注意:在引入jar包之后会出现org.jun ...
- ORACLE——获取随机数
在oracle中获取一个指定的随机数: --(DBMS_RANDOM.VALUE(INT NUM1,INT NUM2),比如: ,) FROM DUAL; --结果:8.23602331029803 ...
- PHP防CC攻击代码
PHP防CC攻击代码: empty($_SERVER['HTTP_VIA']) or exit('Access Denied'); //代理IP直接退出 session_start(); $secon ...
- 安装pwntools及对于解决问题方法搜索的经验总结
安装pwntools 按照网站(https://www.cnblogs.com/xiao3c/p/6799745.html) 中的教程进行安装 下载pwntools 输入命令 git clone ht ...