P5078 Tweetuzki 爱军训
Tweetuzki 爱军训
引言
本文更注重推导过程,无法理解其他题解的可以来这里看看。
解法
考虑贪心。
用
对第
我们计算初始的
我们设
则:
如果
那么我们的核心代码就很好写了:
for(int k = 1;k <= n;k++){
if(pre[n] - pre[k] + (k - n) * w[k] < 0){
ans += -(pre[n] - pre[k] + (k - n) * w[k]);
id[k] = true;
}
}
证明
我们推导的时候会发现,有没有可能选择一个
考虑在我们想要选择
则选择这两个后的
那么
那么我们发现,最后的式子可以拆成
同理可得,无论多少个数选择都不会对彼此造成影响,也就是说这些选择彼此是独立的。
那么贪心即可,代码超短:
#include <iostream>
#include <algorithm>
using namespace std;
#define int long long
const int MAXN = 1e6 + 7;
int n;
int w[MAXN];
bool id[MAXN];
int pre[MAXN];
int ans;
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
for(int i = 1;i <= n;i++) cin >> w[i],pre[i] = pre[i - 1] + w[i];
for(int i = 1;i <= n;i++) pre[i] = pre[i - 1] + w[i],ans += w[i] * i;
for(int k = 1;k <= n;k++){
if(pre[n] - pre[k] + (k - n) * w[k] < 0){
ans += -(pre[n] - pre[k] + (k - n) * w[k]);
id[k] = true;
}
}
cout << ans << endl;
for(int i = 1;i <= n;i++) if(!id[i]) cout << w[i] << " ";
for(int i = n;i >= 1;i--) if(id[i]) cout << w[i] << " ";
return 0;
}
done.
本文来自博客园,作者:wyl123ly,转载请注明原文链接:https://www.cnblogs.com/wyl123ly/p/18457120
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2023-10-10 最短路
2023-10-10 p4801题解