题目链接:https://ac.nowcoder.com/acm/contest/243/A

题目大意:

  略

分析:

  方法就是把疲劳值从小到大排个序,然后从尾部开始一个一个取,当选到第i(i >= 2)个时有2种取法:一是取,那么X = i的答案就是[n-i+1,n]区间的疲劳值求和并加上其中最大距离的2倍;二是不取,那么答案便是[n-i+2,n]区间的疲劳值求和并加上[1,n-i]区间中(疲劳值+距离的2倍)最大的一个,为什么一定是前面那个最大?因为如果最大距离在[n-i+2,n]中,那显然是选取n-i的地方更增加疲劳值。2种取法取个最大即可。
  最大的疑问是,为什么X=i时的最优解一定是建立在[n-i+2,n]区间中的数全部取完之后呢?
证明如下:
  当i = 2时,第n个数是必取的,可以用反证法证明:假设取第x,y(x<y<n)个数时疲劳值最大,于是可以将其中一个不对距离贡献疲劳值的数换成第n个数,这样,无论最大距离是否更新,都出现了一个更优的解,与假设矛盾。
  当i > 2时,也可以用反证法证明:假设在[n-i+2,n]中取m(m<i)个数,在[1,n-i+1]中取i-m个数的组合才是最优的。可以分2种情况:(1)最大距离在[1,n-i+1]区间中,那么[1,n-i+1]区间非最大距离的数都可以用[n-i+2,n]中的数代替,显然可以有更优的解。(2)最大距离在[n-i+2,n]区间中,显然这i个数全部选后i个数是最优的,因为前面的数不对距离有所贡献。综上,与假设矛盾。

代码如下:

 #include <bits/stdc++.h>
using namespace std; #define rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define rFor(i,t,s) for (int i = (t); i >= (s); --i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
#define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i) #define pr(x) cout << #x << " = " << x << " "
#define prln(x) cout << #x << " = " << x << endl #define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin()) #define ms0(a) memset(a,0,sizeof(a))
#define msI(a) memset(a,inf,sizeof(a)) #define pii pair<int,int>
#define piii pair<pair<int,int>,int>
#define mp make_pair
#define pb push_back
#define fi first
#define se second inline int gc(){
static const int BUF = 1e7;
static char buf[BUF], *bg = buf + BUF, *ed = bg; if(bg == ed) fread(bg = buf, , BUF, stdin);
return *bg++;
} inline int ri(){
int x = , f = , c = gc();
for(; c<||c>; f = c=='-'?-:f, c=gc());
for(; c>&&c<; x = x* + c - , c=gc());
return x*f;
} typedef long long LL;
const int maxN = 1e5 + ; int n;
int dist[maxN], cost[maxN];
int suffixMax[maxN]; //记录dist的后缀最大值
int f[maxN]; // f[i]表示当X=1时在1~i范围内只选择1家住户的最优解
int prefixSum[maxN]; // cost的前缀和 int getSum(int x, int y){
return x < y ? prefixSum[y] - prefixSum[x] : ;
} void mergeSort(int l, int r){
if(l >= r) return;
int mid = (l+r) >> ; mergeSort(l, mid);
mergeSort(mid+, r); int tmp1[r-l+], tmp2[r-l+];
int i = l, j = mid + , k = ; while(i <= mid && j <= r){
if(cost[i] > cost[j] || cost[i] == cost[j] && dist[i] > dist[j]){
tmp1[k] = cost[j];
tmp2[k++] = dist[j++];
}
else{
tmp1[k] = cost[i];
tmp2[k++] = dist[i++];
}
}
while(i <= mid){
tmp1[k] = cost[i];
tmp2[k++] = dist[i];
++i;
}
while(j <= r){
tmp1[k] = cost[j];
tmp2[k++] = dist[j];
++j;
} rep(i, k){
cost[i+l] = tmp1[i];
dist[i+l] = tmp2[i];
}
} int main(){
scanf("%d", &n);
For(i, , n) dist[i] = ri();
For(i, , n) cost[i] = ri(); mergeSort(, n);
rFor(i, n, ) suffixMax[i] = max(suffixMax[i+], dist[i]); For(i, , n) f[i] = max(f[i-], cost[i] + dist[i]*); For(i, , n) prefixSum[i] = prefixSum[i-] + cost[i]; rFor(i, n, ) printf("%d\n", max(getSum(i, n) + f[i], getSum(i-, n) + *suffixMax[i]));
return ;
}

NOIP2015普及组复赛A 推销员的更多相关文章

  1. NOIP2015普及组总结

    NOIP2015普及组总结 这次考试总体感觉不错,不过觉得时间有点紧,在最后30分钟才打完. 第一题(金币coin):大大的W!爆搜O(N),一分钟打完: 第二题(扫雷游戏mine):同上: 第三题( ...

  2. NOIP2018普及组复赛游记

    2018年11月10日,NOIP2018普及组复赛. 这是我初中阶段最后一次复赛了. 和往常一样,我们在预定的早上7点,没有出发. 10分钟之后,人终于到齐了,于是出发了,一路无话. 到了南航,合照三 ...

  3. 【题解】NOIP2015提高组 复赛

    [题解]NOIP2015提高组 复赛 传送门: 神奇的幻方 \([P2615]\) 信息传递 \([P2661]\) 斗地主 \([P2668]\) 跳石头 \([P2678]\) 子串 \([P26 ...

  4. [NOIP2015 普及组] 扫雷游戏

    [NOIP2015 普及组] 扫雷游戏 难度:入门 题目描述 扫雷游戏是一款十分经典的单机小游戏.在nn行mm列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格).玩家翻开 ...

  5. NOIP2015普及组第四题推销员

    好久没有写博客了,今天再写一篇.还是先看题: 试题描述 阿明是一名推销员,他奉命到螺丝街推销他们公司的产品.螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户.螺丝街一共有 N 家 ...

  6. NOIP2016普及组复赛解题报告

    提高组萌新,DAY1DAY2加起来骗分不到300,写写普及组的题目聊以自慰. (附:洛谷题目链接 T1:https://www.luogu.org/problem/show?pid=1909 T2:h ...

  7. 洛谷-神奇的幻方-NOIP2015提高组复赛

    题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,--,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第一行的中间. ...

  8. 洛谷【P2669】NOIP2015普及组 T1金币

    我对模拟的理解:http://www.cnblogs.com/AKMer/p/9064018.html 题目传送门:https://www.luogu.org/problemnew/show/P266 ...

  9. 【NOIP2015普及组】推销员_详解

    题目 题目大意 阿明是一名推销员--螺丝街是一条直线,一端有入口,一共有 \(N(<100,000)\) 家住户,第 \(i\) 家住户到入口的距离为 \(S_i\) 米.由于同一栋房子里可以有 ...

随机推荐

  1. [leetcode](4.21)2. 按字典序排列最小的等效字符串

    给出长度相同的两个字符串:A 和 B,其中 A[i] 和 B[i] 是一组等价字符.举个例子,如果 A = "abc" 且 B = "cde",那么就有 'a' ...

  2. C# 定时器-System.Timers.Timer

    using Newtonsoft.Json; using Rafy; using Rafy.Domain; using System; using System.Collections.Generic ...

  3. 上海启动5G试用!104页PPT,为你深度解析5G终端的创新和机遇

    文章发布于公号[数智物语] (ID:decision_engine),关注公号不错过每一篇干货. 来源:国泰君安证券 作者:分析师王聪.张阳.陈飞达 导读:2019年是5G元年,各大品牌将陆续推出5G ...

  4. MongoDB的存储结构及对空间使用率的影响

    MongoDB的存储结构及对空间使用率的影响 使用MongoDB一段时间的同学肯定会发现,MongoDB往往会占用比实际数据大小多不少空间的问题.如果利用db.stats()命令去查看,会发现Mong ...

  5. Error occurred during initialization of VM Could not reserve enough space for 2097152KB object heap

    ionic build Android后的报错问题 ionic 升级了splashscreen和statusbar的插件后,执行ionic build android会一直报打包错误.原因是过低的An ...

  6. 新版的nuget包 PackageLicense 这样写

    Intro 最近编译类库项目的时候发现总是有个 licenseUrl 的警告,警告信息如下: warning NU5125: The 'licenseUrl' element will be depr ...

  7. 使用Ajax轮询模拟简单的站内信箱(消息管理)功能

    前一段时间项目需要写一个类似于站内信箱的消息管理的功能,由于对前端不是很熟悉,刚开始不知道怎么做,后来看了网上的方案,现模拟一个非常简单的消息管理. 我们首先看一下最终效果的样式,就是非常简单的一个样 ...

  8. MySQL InnoDB 日志管理机制中的MTR和日志刷盘

    1.MTR(mini-transaction) 在MySQL的 InnoDB日志管理机制中,有一个很重要的概念就是MTR.MTR是InnoDB存储擎中一个很重要的用来保证物理写的完整性和持久性的机制. ...

  9. Rsync客户端卡死的问题查询

    简介 某备份系统大量使用rsync来传输文件,但是偶尔会出现rsync客户端在上传数据的时候长时间卡死,本文记录了解决问题的步骤. 本文只涉及rsync客户端中IO相关逻辑,关于rsync的发送算法并 ...

  10. Python简介之探观止矣

    Python是一门什么样的编程语言编程语言主要分为编译型和解释型,静态语言和动态语言,强类型和弱类型,混合语言等.编译型语言:通过编译器把源代码编译(compile)成机器语言,在经过链接(linke ...