解:这个题一脸不可做...

比1小的怎么办啊,好像没用,扔了吧。

先看部分分,n = 2简单,我会分类讨论!n = 4简单,我会搜索!n = 10,我会剪枝!

k = 1怎么办,好像选的那些越大越好啊,那么我就排序之后枚举后缀!

k = INF怎么办啊,好像最优策略是从小到大一个一个连通啊,那直接模拟好了。

写一写,有40分了。

别的怎么办啊,拿搜索找规律吧?于是发现一个规律(伪):最优策略一定是单独选择最后k - 1个,和前面的一个后缀。

于是枚举后缀,然后模拟后面的部分,成功得到了61分!

 #include <bits/stdc++.h>

 // ---------- decimal lib start ----------

 // ---------- decimal lib end ----------

 const int N = ;

 int n, k, p;
Decimal a[N]; inline void output(Decimal x) {
std::cout << x.to_string(p + ) << std::endl;
return;
} inline void output(double x) {
printf("%.10f\n", x);
return;
} inline void out(int x) {
for(int i = ; i < n; i++) {
printf("%d", (x >> i) & );
}
return;
} namespace bf { const double eps = 1e-; double ans = , a[N], temp[][];
int lm, pw[], Ans[N], now[N]; void DFS(int x) {
/// check
double large();
for(int i = ; i <= n; i++) {
if(large < a[i]) large = a[i];
}
if(large < ans + eps) {
return;
}
if(fabs(large - a[]) < eps || x > k) {
if(ans < a[]) {
ans = a[];
memcpy(Ans + , now + , x * sizeof(int));
}
return;
} for(int i = ; i <= n; i++) {
temp[x - ][i] = a[i];
}
for(int s = lm - ; s > ; s--) {
if(!(s - (s & (-s)))) continue;
double tot = ;
int cnt = ;
int t = s;
while(t) {
int tt = pw[t & (-t)] + ;
tot += a[tt];
cnt++;
t ^= << (tt - );
}
tot /= cnt;
t = s;
while(t) {
int tt = pw[t & (-t)] + ;
a[tt] = tot;
t ^= << (tt - );
}
now[x] = s;
DFS(x + );
t = s;
while(t) {
int tt = pw[t & (-t)] + ;
a[tt] = temp[x - ][tt];
t ^= << (tt - );
}
}
now[x] = ;
return;
} inline void solve() { /// DFS
lm = << n;
for(int i = ; i < n; i++) {
pw[ << i] = i;
}
for(int i = ; i <= n; i++) {
a[i] = ::a[i].to_double();
}
DFS(); output(ans); /*for(int i = 1; i <= k + 1; i++) {
out(Ans[i]); printf(" ");
}
puts("");*/
return;
}
} int main() { //freopen("in.in", "r", stdin); scanf("%d%d%d", &n, &k, &p);
for(int i = , x; i <= n; i++) {
scanf("%d", &x);
a[i] = x;
} std::sort(a + , a + n + );
if(n == ) {
output(a[]);
return ;
}
if(n == ) {
if(a[] > a[]) {
output(a[]);
}
else {
a[] = (a[] + a[]) / ;
output(a[]);
}
return ;
}
if(a[] >= a[n]) {
output(a[]);
return ;
}
if(k == ) {
Decimal tot = a[], ans = a[];
int cnt = ;
for(int i = n; i >= ; i--) {
cnt++;
tot += a[i];
ans = std::max(ans, tot / cnt);
}
output(ans);
return ;
}
if(k >= n - ) {
for(int i = ; i <= n; i++) {
if(a[] > a[i]) continue;
a[] = (a[] + a[i]) / ;
}
output(a[]);
return ;
}
if(n <= ) {
bf::solve();
return ;
}
else {
Decimal tot = a[], ans = a[];
int cnt = ;
for(int i = n - k + ; i >= ; i--) {
cnt++;
tot += a[i];
ans = std::max(ans, tot / cnt);
}
a[] = ans;
for(int i = n - k + ; i <= n; i++) {
if(a[] > a[i]) continue;
a[] = (a[] + a[i]) / ;
}
output(a[]);
return ;
}
return ;
}

61分代码

正确的规律:最优策略一定是把一个后缀分成连续若干段。

于是以此DP,设f[i][j]表示前i次操作取到了j,此时1号点的最大值。转移就枚举从哪来即可。注意初始化。

 #include <bits/stdc++.h>

 // ---------- decimal lib start ----------

 const int PREC = ;

 // ---------- decimal lib end ----------

 const int N = ;

 int n, k, p;
Decimal a[N]; inline void output(Decimal x) {
std::cout << x.to_string(p + ) << std::endl;
return;
} inline void output(double x) {
printf("%.10f\n", x);
return;
} inline void out(int x) {
for(int i = ; i < n; i++) {
printf("%d", (x >> i) & );
}
return;
} namespace bf { const double eps = 1e-; double ans = , a[N], temp[][];
int lm, pw[], Ans[N], now[N]; void DFS(int x) {
/// check
double large();
for(int i = ; i <= n; i++) {
if(large < a[i]) large = a[i];
}
if(large < ans + eps) {
return;
}
if(fabs(large - a[]) < eps || x > k) {
if(ans < a[]) {
ans = a[];
memcpy(Ans + , now + , x * sizeof(int));
}
return;
} for(int i = ; i <= n; i++) {
temp[x - ][i] = a[i];
}
for(int s = lm - ; s > ; s--) {
if(!(s - (s & (-s)))) continue;
double tot = ;
int cnt = ;
int t = s;
while(t) {
int tt = pw[t & (-t)] + ;
tot += a[tt];
cnt++;
t ^= << (tt - );
}
tot /= cnt;
t = s;
while(t) {
int tt = pw[t & (-t)] + ;
a[tt] = tot;
t ^= << (tt - );
}
now[x] = s;
DFS(x + );
t = s;
while(t) {
int tt = pw[t & (-t)] + ;
a[tt] = temp[x - ][tt];
t ^= << (tt - );
}
}
now[x] = ;
return;
} inline void solve() { /// DFS
lm = << n;
for(int i = ; i < n; i++) {
pw[ << i] = i;
}
for(int i = ; i <= n; i++) {
a[i] = ::a[i].to_double();
}
DFS(); output(ans); /*for(int i = 1; i <= k + 1; i++) {
out(Ans[i]); printf(" ");
}
puts("");*/
return;
}
} Decimal f[][];
int sum[N]; inline void solve() {
int I = ;
while(a[] > a[I]) ++I;
for(int i = ; i <= n; i++) {
f[][i] = a[];
}
for(int i = ; i <= k; i++) {
f[i][I - ] = a[];
for(int j = I; j <= n; j++) {
/// f[i][j]
f[i][j] = f[i - ][j];
for(int p = I - ; p < j; p++) {
Decimal t = (f[i - ][p] + sum[j] - sum[p]) / (j - p + );
if(f[i][j] < t) {
f[i][j] = t;
}
}
//printf("i = %d j = %d f = ", i, j); output(f[i][j]);
}
}
output(f[k][n]);
return;
} int main() { //freopen("in.in", "r", stdin);
//printf("%d \n", (sizeof(f)) / 1048576); scanf("%d%d%d", &n, &k, &p);
for(int i = , x; i <= n; i++) {
scanf("%d", &x);
a[i] = x;
} std::sort(a + , a + n + );
for(int i = ; i <= n; i++) {
sum[i] = sum[i - ] + (int)(a[i].to_double() + 0.5);
}
if(n == ) {
output(a[]);
return ;
}
if(n == ) {
if(a[] > a[]) {
output(a[]);
}
else {
a[] = (a[] + a[]) / ;
output(a[]);
}
return ;
}
if(a[] >= a[n]) {
output(a[]);
return ;
}
if(k == ) {
Decimal tot = a[], ans = a[];
int cnt = ;
for(int i = n; i >= ; i--) {
cnt++;
tot += a[i];
ans = std::max(ans, tot / cnt);
}
output(ans);
return ;
}
if(k >= n - ) {
for(int i = ; i <= n; i++) {
if(a[] > a[i]) continue;
a[] = (a[] + a[i]) / ;
}
output(a[]);
return ;
}
if(n <= ) {
bf::solve();
return ;
}
else {
solve();
return ;
}
return ;
}

60分代码

考虑如何优化这个DP。

LOJ#2087 国王饮水记的更多相关文章

  1. 【BZOJ4654】【NOI2016】国王饮水记(动态规划,斜率优化)

    [BZOJ4654][NOI2016]国王饮水记(动态规划,斜率优化) 题面 BZOJ 洛谷 题解 首先肯定是找性质. 明确一点,比\(h_1\)小的没有任何意义. 所以我们按照\(h\)排序,那么\ ...

  2. [UOJ#223][BZOJ4654][Noi2016]国王饮水记

    [UOJ#223][BZOJ4654][Noi2016]国王饮水记 试题描述 跳蚤国有 n 个城市,伟大的跳蚤国王居住在跳蚤国首都中,即 1 号城市中.跳蚤国最大的问题就是饮水问题,由于首都中居住的跳 ...

  3. luogu P1721 [NOI2016]国王饮水记 斜率优化dp 贪心 决策单调性

    LINK:国王饮水记 看起来很不可做的样子. 但实际上还是需要先考虑贪心. 当k==1的时候 只有一次操作机会.显然可以把那些比第一个位置小的都给扔掉. 然后可以得知剩下序列中的最大值一定会被选择. ...

  4. [Noi2016]国王饮水记

    来自FallDream的博客,未经允许,请勿转载,谢谢. 跳蚤国有 n 个城市,伟大的跳蚤国王居住在跳蚤国首都中,即 1 号城市中.跳蚤国最大的问题就是饮水问题,由于首都中居住的跳蚤实在太多,跳蚤国王 ...

  5. BZOJ4654/UOJ223 [Noi2016]国王饮水记

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  6. uoj233/BZOJ4654/洛谷P1721 [Noi2016]国王饮水记 【dp + 斜率优化】

    题目链接 uoj233 题解 下面不加证明地给出几个性质: 小于\(h[1]\)的城市一定是没用的 任何城市联通包含\(1\)且只和\(1\)联通一次 联通顺序从小到大最优 单个联通比多个一起联通要优 ...

  7. [NOI 2016]国王饮水记

    Description 题库链接 给出 \(n\) 个水杯,每个水杯装有不同高度的水 \(h_i\) ,每次可以指定任意多水杯用连通器连通后断开,问不超过 \(k\) 次操作之后 \(1\) 号水杯的 ...

  8. *UOJ#223. 【NOI2016】国王饮水记

    $n \leq 8000$的数列,问不超过$m \leq 1e9$次操作后第一个数字最大是多少.操作:选一些数,把他们变成他们的平均值.需要保留$p \leq 3000$位小数,提供了一个小数高精度库 ...

  9. BZOJ4654 NOI2016国王饮水记(动态规划+三分)

    有很多比较显然的性质.首先每个城市(除1外)至多被连通一次,否则没有意义.其次将城市按水位从大到小排序后,用以连通的城市集合是一段前缀,并且不应存在比1城市还小的.然后如果确定了选取的城市集合,每次选 ...

随机推荐

  1. Poj1477

    Box of Bricks Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 24101   Accepted: 9378 De ...

  2. 驰骋开源的asp.net工作流程引擎java工作流 2015 正文 驰骋工作流引擎ccflow6的功能列表

    关键词: 驰骋工作流引擎   ccflow的功能列表   工作流功能列表  表单引擎功能列表 我们工作流引擎ccflow6重构之后对功能做了一些调整,要想快速了解ccbpm的功能,可以以下面列表为准 ...

  3. 测者的测试技术手册:Java中的null类型是测试不可超越的鸿沟

    null是一个非常非常特殊的类型,对于每一个测试人员都要十分小心null的存在的可能性.同时null也让很多RD头疼,甚至连Java的设计者都成人null是一个设计失误.这篇文章,测者想聊聊这个让很多 ...

  4. CentOS7.x安装MySQL5.7.25

    mysql 5.7下载地址 社区版下载地址:https://dev.mysql.com/downloads/mysql/ 可能会有变动 找到5.7版本, 注:源码安装需要用到下面的包,可以先忽略,我安 ...

  5. 10 Django RESTful api 实现匿名访问

    # views_send_code.py from rest_framework.permissions import AllowAny class MsgCodeViewSet(CreateMode ...

  6. 转载:img是什么元素?置换元素?

    转载: https://blog.csdn.net/kingliguo/article/details/52643594 img是什么元素? 应是行内元素,判断一个元素是行内元素,还是块元素,无非就是 ...

  7. Google SRE

    SRE_百度百科 https://baike.baidu.com/item/SRE/1141123 我们离Google SRE还有多远? - 简书https://www.jianshu.com/p/6 ...

  8. dataTables 插件学习整理

    在项目中使用了dataTables 插件,学习整理一下. dataTables 的官方中文网站 http://www.datatables.club 引入文件: 所有的都要引入 jq文件 1. dat ...

  9. 浅析Java数据类型

    前言: 该系列会辅以MindMap进行说明. 下面会贴两张我不同时期画的Java数据类型的思维导图,本篇主要侧重于Java的8种基本类型 MindMap-1 这张MindMap主要是根据 菜鸟教程+参 ...

  10. springboot aop 拦截接口执行时间

    /** * @description: 记录接口执行时间日志的记录 * @author: * @create 2018-12-27 16:32 */ @Target(ElementType.METHO ...