1. 程式人生 > >Codeforces 101623E English Restaurant

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

  1 /**
  2  * Codeforces
  3  * Gym#101623E
  4  * Accepted
  5  * Time: 46ms
  6  * Memory: 2600k
  7  */
  8 #include <algorithm>
  9
#include <iostream> 10 #include <cstdlib> 11 #include <cstdio> 12 #include <vector> 13 using namespace std; 14 typedef bool boolean; 15 16 typedef long double ld; 17 typedef pair<ld, ld> pdd; 18 19 pdd operator + (const pdd& a, const pdd& b) {
20 return pdd(a.first + b.first, a.second + b.second); 21 } 22 23 pdd operator * (const pdd& a, const pdd& b) { 24 return pdd(a.first * b.second + a.second * b.first, a.second * b.second); 25 } 26 27 pdd operator * (const pdd& a, ld x) { 28 return pdd(a.first * x, a.second * x); 29 } 30 31 ld nature_sum(int x) { 32 return x * (x + 1) >> 1; 33 } 34 35 const int N = 105; 36 37 int n, g, t; 38 vector<int> c; 39 ld C[N << 1][N << 1]; 40 pdd f[N << 1][N << 1], h[N][N << 1], s[N][N << 1]; 41 42 inline void init() { 43 scanf("%d%d%d", &n, &g, &t); 44 c.resize(n); 45 for (int i = 0; i < n; i++) { 46 scanf("%d", &c[i]); 47 c[i] = min(c[i], g); 48 } 49 for (int i = 0; i < t; i++) 50 c.push_back(g + 1); 51 sort(c.begin(), c.end()); 52 n = c.size(); 53 } 54 55 inline void solve() { 56 C[0][0] = 1; 57 for (int i = 1; i <= n; i++) { 58 C[i][0] = C[i][i] = 1; 59 for (int j = 1; j < i; j++) 60 C[i][j] = C[i - 1][j] + C[i - 1][j - 1]; 61 } 62 63 for (int r = 0; r < n; r++) 64 for (int l = r; ~l; l--) { 65 for (int mid = l; mid <= r; mid++) { 66 pdd val; //(0, 1);//C[r - l][r - mid]); 67 if (c[mid] > g) 68 val = pdd(0, g - ((l) ? (min(c[l - 1], g)) : (0))); 69 else 70 val = pdd(nature_sum(c[mid]) - ((l) ? (nature_sum(c[l - 1])) : (0)), c[mid] - ((l) ? (c[l - 1]) : (0))); 71 pdd vall = (mid > l) ? (f[l][mid - 1] * C[r - l][r - mid]) : (pdd(0, 1)); 72 pdd valr = (mid < r) ? (f[mid + 1][r]) : (pdd(0, 1)); 73 f[l][r] = f[l][r] + (vall * val * valr); 74 } 75 // cerr << l << " " << r << " " << f[l][r].first << " " << f[l][r].second << '\n'; 76 } 77 78 for (int i = 0; i < t; i++) 79 for (int j = 0; j < n - t + i + 1; j++) 80 h[i][j] = f[j][j + t - i - 1]; 81 for (int i = t; i--; ) { 82 int all = t - i; 83 for (int j = 0; j + all < n; j++) { 84 for (int k = i + 1; k < t; k++) { 85 int put = k - i; 86 // cerr << i << " " << j << " " << k << " " << all << " " << put << '\n'; 87 ld comb = C[all][put]; 88 h[i][j] = h[i][j] + (f[j][j + put - 1] * comb * s[k][j + put + 1]); 89 } 90 // cerr << i << " " << j << " " << h[i][j].first << " " << h[i][j].second << '\n'; 91 } 92 s[i][n - 1] = h[i][n - 1]; 93 for (int j = n - 2; j >= 0; j--) 94 s[i][j] = s[i][j + 1] + h[i][j]; 95 } 96 pdd ans(0, 0); 97 for (int i = 0; i < n; i++) 98 ans = ans + h[0][i]; 99 // cout << (ans.first / ans.second) << '\n'; 100 double E = ans.first / ans.second; 101 printf("%.9lf", E); 102 } 103 104 int main() { 105 init(); 106 solve(); 107 return 0; 108 }

相關推薦

Codeforces 101623E English Restaurant - 動態規劃

題目傳送門   傳送門 題目大意   餐廳有$n$張桌子,第$i$張桌子可以容納$c_i$個人,有$t$組客人,每組客人的人數等概率是$[1, g]$中的整數。   每來一組人數為$x$客人,餐廳如果能找到最小的$c_j$使得$c_j \geqslant x$,那麼就會把這張桌子分配

Codeforces 101623E English Restaurant

題目傳送門   傳送門 題目大意   餐廳有$n$張桌子,第$i$張桌子可以容納$c_i$個人,有$t$組客人,每組客人的人數等概率是$[1, g]$中的整數。   每來一組人數為$x$客人,餐廳如果能找到最小的$c_j$使得$c_j \geqslant x$,那麼就會把這張桌子分配給這些客人

【區間DP+期望】Gym101623E English Restaurant

【題目】 原題地址 一個餐廳有 n n n張桌子,第

Codeforces 597B Restaurant(離散化 + 貪心)

ces struct lower c++ 排好序 bit ont scanf sin 題目鏈接 Restaurant 題目意思就是在n個區間內選出盡可能多的區間,使得這些區間互不相交。 我們先對這n個區間去重。 假如有兩個區間[l1, r1],[l2, r2] 若滿

Codeforces Testing Round 12B】【貪心】Restaurant 選取數量最多的不覆蓋區間數

B. Restaurant time limit per test 4 seconds memory limit per test 256 megabytes input s

Codeforces 803G Periodic RMQ Problem ST表+動態開節點線段樹

ces 細節 ren urn 區間覆蓋 d+ ins cstring pro 思路: (我也不知道這是不是正解) ST表預處理出來原數列的兩點之間的min 再搞一個動態開節點線段樹 節點記錄ans 和標記 lazy=-1 當前節點的ans可用 lazy=0 沒被

codeforces 798C Mike and gcd problem

opera can sample pan using str ssl else font C.Mike and gcd problem Mike has a sequence A?=?[a1,?a2,?...,?an] of length n. He cons

【推導】Codeforces Round #411 (Div. 1) A. Find Amir

div sca ace space for amp clu ret blog 1 2 3 4 5 6 7 4-5-3-6-2-7-1 答案是(n-1)/2 #include<cstdio> using namespace std; int n; int mai

Codeforces 55D Beautiful numbers(數位dp)

pac urn etc number div clu 能夠 是我 tdi   題目大意:T(<=10)組數據,求[a,b]能夠被其每個數位的數都整除的數(a,b<=9*10^18)   這題差一點就想出來了,可是最後一步好難想也好妙啊   首先這個數能夠整除各個

A - Superset CodeForces - 97B(人生第一個分治法,感覺,像二分啊。。)

但是 ++ 是什麽 force else super 結構體 運算 代碼 /* 分治法,第一次做不是很懂,借鑒了神犇代碼,但實操之後感覺像二分,,可能做得少了或者就是。。。。 */ 題目大意: 一個集合裏有若幹點,要求你添加某些點後保證這個集合裏的任意兩點滿足以下三個條件中

Codeforces 601A

pan clas cout continue bre esp scan ace bsp #include <bits/stdc++.h> using namespace std; #define maxn 411 #define INF 11111

Codeforces Round #263 (Div.1) B. Appleman and Tree

ace apple n+1 test right art [0 pan target 題目地址:http://codeforces.com/contest/461/problem/B 題目大意:給一棵樹。每一個點為白色或黑色。切斷一些邊,使得每一個連通塊有且僅有一個黑點

codeforces 797 E. Array Queries【dp,暴力】

round codeforce ems 狀態轉移方程 printf ret scan std spa 題目鏈接:codeforces 797 E. Array Queries 題意:給你一個長度為n的數組a,和q個詢問,每次詢問為(p,k),相應的把p轉換為p+a[

Codeforces:"North-East"

nor font sort pan pos ace ons lower insert Codeforces:"North-East" 題目鏈接:http://codeforces.com/gym/101246/problem/H 題目大意:空間內有$n$個點,現取$x$

Codeforces Round #221 (Div. 2) D

cpp 位置 input memset ont code init cal 矩形 有點郁悶的題目,給了2000ms,可是n,m的範圍已經是5000了。5000 * 5000一般在別的OJ已經是超了2000ms,一開始不敢敲。看了下別人有n*m的潛逃循環,原來CF的機子如

Codeforces Round #412 (rated, Div. 2, base on VK Cup 2017 Round 3) B. T-Shirt Hunt

seconds ack ble pseudo lose tinc += repeat ac代碼 B. T-Shirt Hunt time limit per test2 seconds memory limit per test256 megabytes inputsta

Codeforces Round #412 (rated, Div. 2, base on VK Cup 2017 Round 3) E. Prairie Partition 二分+貪心

必須 could col clas == show with str ati E. Prairie Partition It can be shown that any positive integer x can be uniquely re

codeforces之始

參加 而是 傳統 交流 運行時 表達 都是 習慣 交通 很早就聽說acmer界的CF嘞!還記得剛開始聽到神犇們在討論CF的時候我還以為是網遊CF(穿越火線)呢。。。 今年剛開學的時候就打算開始打cf的,由於一些事情耽擱了。之後又要準備省賽所以就一直拖到現在(其實還是自己懶

2017-5-2-Train:Codeforces Round #323 (Div. 2)

width ins exp seq main ons mon tel exists A. Asphalting Roads(模擬) City X consists of n vertical and n horizontal infinite roads, forming

CodeForces 797B Odd sum

amp ios cto sca 1+n 改變 printf pri logs 排序。 正的偶數肯定都是可以加進去的,因為加偶數不改變奇偶性。奇數從大到小排序,取個最大的前綴和。 #include <iostream> #include <cstd