CF97C Winning Strategy 构造、图论
题目传送门:http://codeforces.com/problemset/problem/97/C
题意:给出$n$与一个范围在$[0,1]$内的递增序列$P_0-P_n$,试构造一个无穷序列$\{a_i\}$满足$0 \leq a_i \leq n$,使得对于任意$k > 0$满足$a_k \leq \sum\limits_{i=1}^{k-1}(n - 2a_i)$且极限$\lim\limits_{m \rightarrow +\infty} \frac{\sum\limits_{i=1}^mp_{a_i}}{m}$达到最大,给出这个最大值。$N \leq 100$
因为数列无限,所以显然不能够将这个数列表示出来,故考虑构造一个循环节,使这个循环节的平均值最大,然后无限循环这个循环节,就能够得到最大的平均值。所以我们考虑找到一个有限数列使得其平均值最大。
方法一:
考虑转换模型。令$Q=\sum\limits_{i=1}^{k-1}(n - 2a_i)$,对于$a_k$,它会造成$P_{a_k}$的贡献并使得$Q+=n-2a_k=-a_k+(n-a_k)$,也就是待选的范围$Q$减掉了$a_k$,又补上了$n-a_k$。故考虑:最开始我们有一个箱子,其中有$0$个物品,第$i$次从箱子中拿出$a_i$个物品,并补进$n-a_i$个物品,求$\lim\limits_{m \rightarrow +\infty} \frac{\sum\limits_{i=1}^mp_{a_i}}{m}$的最大值。
接下来我们能发现某一个时刻的决策只与其对应的$Q$有关,与时刻无关,所以我们可以将$Q$的取值看成点,决策转换看成边,边权是对应的贡献,构出一个图。可以知道其中对应箱子中物品数量大于$2n$的点显然是没有意义的,因为从其中取出$n$个得到$P_n$的贡献仍然能够覆盖所有的$0-n$的取值。所以我们的点数只有$2n$个($0$点也是没有意义的,因为最优解一定不会出现在$0$号点)。
回到我们需要求的东西,是一个循环节,对应在图中是一个环。所以我们需要找的是图上一个平均边权最大的环。这个显然是可以二分的,check函数将所有边权减掉mid,用spfa判断正环即可。时间复杂度约为$O(N^3)$
#include<bits/stdc++.h>
#define R register
#define MAXN 100010
#define eps 1e-9
using namespace std;
] , dis[];
short N , K;
queue < int > q;
struct Edge{
int end , upEd;
double w;
}Ed[MAXN];
] , flo[] , cntEd;
];
inline void addEd(int a , int b , double c){
Ed[++cntEd].end = b;
Ed[cntEd].w = c;
Ed[cntEd].upEd = head[a];
head[a] = cntEd;
}
inline bool check(double mid){
while(!q.empty())
q.pop();
memset(dis , 0xdd , sizeof(dis));
memset(inq , , sizeof(inq));
memset(flo , , sizeof(flo));
dis[flo[] = ] = ;
q.push();
while(!q.empty()){
int t = q.front();
q.pop();
inq[t] = ;
for(int i = head[t] ; i ; i = Ed[i].upEd)
if(dis[Ed[i].end] < dis[t] + Ed[i].w - mid){
dis[Ed[i].end] = dis[t] + Ed[i].w - mid;
flo[Ed[i].end] = flo[t] + ;
if(flo[Ed[i].end] > K)
;
if(!inq[Ed[i].end]){
inq[Ed[i].end] = ;
q.push(Ed[i].end);
}
}
}
;
}
inline void solve(){
; i <= K ; i++)
; j <= K ; j++){
int k = i - j;
) == (N & ))
addEd(i , j , p[N + i - j >> ]);
}
, r = ;
while(r - l > eps){
;
check(mid) ? l = mid : r = mid;
}
printf("%.8lf" , l);
}
int main(){
scanf("%d" , &N);
K = N << ;
; i <= N ; ++i)
scanf("%lf" , &p[i]);
solve();
;
}
方法二:
由我们的图论模型可以得出一个结论:我们只会选一种$n-2a_i>0$的$a_i$和一种$n-2a_i<0$的$a_i$。
证明:
考虑同时选取了$a_j$与$a_k$使得$n-2a_j<0$且$n-2a_k<0$,考虑进行$(n-2a_j)(n-2a_k)$的物品拿出
对于选择$j$有$P_j(n-2a_k)$的贡献,对于选择$k$有$P_k(n-2a_j)$的贡献,我们假设$P_j(n-2a_k)>P_k(n-2a_j)$
那么我们进行无限次之后,假定这个次数为$(n-2a_j)(n-2a_k)$的倍数,这样选择$j$的贡献仍然大于选择$k$的贡献,故选择$j$更好。
大于$0$的情况考虑物品贡献即可。
所以我们可以枚举较小的一个$a_i$和较大的一个$a_j$算出以它们为循环节时的答案,所有的答案取$max$即可,时间复杂度为$O(n^2)$
注意:当$n$为偶数时,$\frac{n}{2}$需要特殊判断。
#include<bits/stdc++.h>
using namespace std;
];
int main(){
int N;
;
cin >> N;
; i <= N ; i++)
cin >> p[i];
; i <= N - >> ; i++)
) + ; j <= N ; j++)
* j - N) + p[j] * (N - * i)) / (- * i + * j) > ans)
ans = (p[i] * ( * j - N) + p[j] * (N - * i)) / (- * i + * j);
) == )
ans = max(ans , p[N >> ]);
cout << ) << ans;
;
}
CF97C Winning Strategy 构造、图论的更多相关文章
- CF97C Winning Strategy
CF97C Winning Strategy 洛咕(题意应该快传上去了) 这题好玄学鸭...都不知道为啥是对的 设\(f[i][j]\)表示打了i轮比赛,有j个参加了一次的人,直接枚举有几个参加了转移 ...
- 题解 CF97C 【Winning Strategy】
题解 CF97C [Winning Strategy] 此题是某平台%你赛原题,跟大家分享一下某校zsy和sxr等同学的神仙做法. 我解释一下题意,大是说,我有[无限]个人,每个人可以对他" ...
- CCO2017 Vera and Trail Building 构造+图论
正解:构造+图论 解题报告: 找了半天才找到的传送门! 先简要表达下题意 一个图上,如果存在(a,b)满足a<b且存在从a到b再回到a的路径,每条道路被经过至多一次,我们称(a,b)为完美点对试 ...
- Johnny Solving CodeForces - 1103C (构造,图论)
大意: 无向图, 无重边自环, 每个点度数>=3, 要求完成下面任意一个任务 找一条结点数不少于n/k的简单路径 找k个简单环, 每个环结点数小于n/k, 且不为3的倍数, 且每个环有一个特殊点 ...
- mark一下咕掉的题目
蒟蒻才普及组呀~ 大佬别D我 等集中补一下 CF980F:咋说捏,我觉得要联赛了做这题有点浪费时间,等想颓废了再来写写叭qwq 215E/279D/288E/331C3/431D/433E/750G/ ...
- 【POJ1568】【极大极小搜索+alpha-beta剪枝】Find the Winning Move
Description 4x4 tic-tac-toe is played on a board with four rows (numbered 0 to 3 from top to bottom) ...
- poj1568 Find the Winning Move[极大极小搜索+alpha-beta剪枝]
Find the Winning Move Time Limit: 3000MS Memory Limit: 32768K Total Submissions: 1286 Accepted: ...
- Codeforces Round #360 (Div. 2) D. Remainders Game 中国剩余定理
题目链接: 题目 D. Remainders Game time limit per test 1 second memory limit per test 256 megabytes 问题描述 To ...
- poj 2068 Nim(博弈树)
Nim Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 1501 Accepted: 845 Description Le ...
随机推荐
- python之if循环
if 条件: if语句块else: 语句块 money = int(input("请输入你兜里的钱:")) if money > 500: print("吃肉&qu ...
- 从输入url到页面展示到底发生了什么
阅读目录 1.输入地址 2.浏览器查找域名的 IP 地址 3.浏览器向 web 服务器发送一个 HTTP 请求 4.服务器的永久重定向响应 5.浏览器跟踪重定向地址 6.服务器处理请求 7.服务器返回 ...
- ActiveReports公开课开启报名,学习如何解决中国式复杂报表难题
ActiveReports实战教学 90分钟解决中国式复杂报表六大需求 [开课时间]4月19日 [主讲老师]葡萄城资深报表专家 [培训方式]网络在线公开课 报名地址
- IDEA错误:Failed to start end point associated with ProtocolHandler [http-nio-9999] java.net.BindException: Address already in use: bind
日志显示进程端口已被占用,首先需要的是查询什么进程占用了当前的9999端口. 1.win+R输入cmd进入命令界面: 2.输入命令 netstat -ano|findstr "端口号&qu ...
- GridView的簡單使用
項目GitHub地址:https://github.com/leonInShanghai/IMbobo GridView XML佈局: <?xml version="1.0" ...
- recovery 恢复出厂设置失败Data wipe failed
最近客户反馈,编译32位的android系统,在recovery中执行恢复出厂设置的时候失败了,失败的打印提升信息如下. Formatting /data... [ 2.191404] E:get_f ...
- Python类继承,方法重写及私有方法
# -*- coding: utf-8 -*- """ Created on Mon Nov 12 15:05:20 2018 @author: zhen "& ...
- persist与checkpoint
1.当反复使用某些RDD时建议使用persist(缓存级别)(采用默认缓存级别时为cache())来对数据进行缓存. 2.如果某个步骤的RDD计算特别耗时或经历很多步骤的计算,当重新计算时代价特别大, ...
- selenium+python自动化笔记之一
一.webdriver的API与定位元素 元素定位核心部分 元素名称 webdriver API 说明 id find_element_by_id() id定位 name find_element_b ...
- Java jni字符串转换
1.jstring转QString 对于Qt5.2以上(含)可以用QAndroidJniObject::toString(),详见这里:https://stackoverflow.com/questi ...