P5308 [COCI2019] Quiz

1|0P5308 [COCI2019] Quiz

1|1题目描述:

规定贡献为 选出来的数总数 ,问恰好经过 k 次选数,最多能获得的贡献。

1|2题目分析:

直接暴力单调性转移 40 滚粗。。

貌似是 dp 的倒退?但是正着推也是可以做的。

首先很显然的一个 dp

dp[i][k]=max0j<i(dp[j][k1]+ijnj)

就是表示前 i 个里面选 j 次,是一个划分性 dp

考虑斜率优化(话说我已经好长时间没写过斜率优化了)

dp[j][k1]jnj=(i)×1nj+dp[i][k]

dp[i][k1]y1njx(i)kdp[i][k]b

然后 xk 均满足单调性,直接在凸包上进行斜率优化即可。但是很明显过不去是吧, 然后你定睛一看,这是个凸函数(证明先咕了),套上 wqs 二分即可(怎么考的都是我很长时间没碰的东西啊喂

1|3Code:

//editor : DRYAYST //Wo shi ge da SHA BI #include<bits/stdc++.h> #define g() getchar() #define il inline #define ull unsigned long long #define eps 1e-14 #define ll long long #define pa pair<int, int> #define for_1(i, n) for(int i = 1; i <= (n); ++i) #define for_0(i, n) for(int i = 0; i < (n); ++i) #define for_xy(i, x, y) for(int i = (x); i <= (y); ++i) #define for_yx(i, y, x) for(int i = (y); i >= (x); --i) #define for_edge(i, x) for(int i = head[x]; i; i = nxt[i]) #define int long long #define DB long double #define ls (p<<1) #define rs (p<<1|1) #define m_p make_pair #define fi first #define se second using namespace std; const int N = 2e5 + 10, INF = 0x7f7f7f7f, mod = 1e9 + 7; il int qpow(int x, int k) {int ans = 1; while(k) {if(k & 1) ans = ans * x % mod; x = x * x % mod; k >>= 1; } return ans; } il int Add(int x, int y) {return (x += y) %= mod;} il int Del(int x, int y) {return (x = x - y + mod) % mod;} il int Mul(int x, int y) {return x * y % mod;} il int inv(int x) {return qpow(x, mod - 2); } inline int re() { int x = 0, p = 1; char ch = getchar(); while(ch > '9' || ch < '0') {if(ch == '-') p = -1; ch = getchar();} while(ch <= '9' and ch >= '0') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();} return x * p; } int n, K, head, tail; int q[N], num[N]; DB dp[N]; il DB X(int x) {return 1.0 / (n - x); } il DB Y(int x) {return dp[x] - 1.0 * (x) / (n - x); } il DB work(int x, int y) {return (Y(y) - Y(x)) / (X(y) - X(x)); } il bool Check(DB x) { head = tail = 1; for(int i = 1; i <= n; ++i) { while(head < tail and work(q[head], q[head+1]) >= (-1.0 * i)) ++head; dp[i] = Y(q[head]) + i * X(q[head]) - x; num[i] = num[q[head]] + 1; while(head < tail and work(q[tail - 1], q[tail]) <= work(q[tail], i)) --tail; q[++tail] = i; } return num[n] >= K; } signed main() { freopen("talk.in","r",stdin); freopen("talk.out","w",stdout); n = re(), K = re(); DB l = 0, r = INF; while(r - l > eps) { DB mid = (l + r) / 2; if(Check(mid)) l = mid; else r = mid; } Check(l); printf("%.9Lf\n", dp[n] + 1.0 * l * K); }

__EOF__

本文作者Zwaire
本文链接https://www.cnblogs.com/Zwaire/p/16102200.html
关于博主:这个世界除了你,都知道我喜欢你
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Zwaire  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示