博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【BZOJ】2697: 特技飞行
阅读量:6326 次
发布时间:2019-06-22

本文共 975 字,大约阅读时间需要 3 分钟。

题意

\(k(1 \le k \le 300)\)种物品,价值分别为\(c_i(0 \le c_i \le 1000)\)。有\(n(1 \le n \le 1000)\)分钟,每分钟可以选择一个物品\(i\),价值为距离上次选择该物品的时间 * \(c_i\)。求最大价值。

分析

发现对于一种物品,价值为\(c_i * \sum_{j=2}^{a} (t_j-t_{j-1}) = c_i * (t_a-t_1)\)\(t_i\)表示第\(i\)次选这个物品的时间。这样,我们只需要为每一个物品找到一个开始和结束时间的时间即可。

由于考虑任意两种物品及其位置对其它的物品的贡献无影响,所以我们考虑任意两种物品。
对于两种物品\(i, j\),假设\(c_i \ge c_j\),他们开始和结束时间分别为\(l_i, r_i\)\(l_j, r_j\),则最优解中肯定\(l_i < l_j, r_j < r_i\),证明如下:
首先显然肯定不可能\(l_j < l_i, r_i < r_j\)
假设\(l_i < l_j, r_i < r_j\)\(l_j < l_i, r_j < r_i\)证明类似),则可以证明将\(r_i, r_j\)交换后更优(证明大简单,略)。
所以我们将物品排序后,一个个取即可。

题解

所以贪心地取即可

#include 
using namespace std;typedef long long ll;const int N=500005;int n, k, a[N];int main() { scanf("%d%d", &n, &k); for(int i=1; i<=k; ++i) { scanf("%d", &a[i]); } sort(a+1, a+1+k); int num=n-1; ll ans=0; for(int i=k; i; --i) { if(num<0) { break; } ans+=(ll)num*a[i]; num-=2; } printf("%lld\n", ans); return 0;}

转载地址:http://xngaa.baihongyu.com/

你可能感兴趣的文章
vs2010生成Dll文件并引用dll(C#)
查看>>
藏在兰州拉面里精益管理秘诀
查看>>
百思不得姐 one day
查看>>
19.04.16--指针笔记-参数传递
查看>>
POJ1860 Currency Exchange
查看>>
《VMware、Citrix和Microsoft虚拟化技术详解与应用实践》一2.2 ESXi简介
查看>>
[游戏学习22] MFC 井字棋 双人对战
查看>>
Qt中的qreal
查看>>
Codeforces Beta Round #95 (Div. 2) D.Subway
查看>>
企业搜索引擎开发之连接器connector(二十)
查看>>
HeadFirst Jsp 09 (JSTL)
查看>>
jquery版小型婚礼(可动态添加祝福语)
查看>>
Centos5.8 安装 PHP5.5 和 memcached
查看>>
[转]CENTOS LINUX安装并使用NFS共享文件
查看>>
Android AES加密算法及其实现
查看>>
Entity Framework公共的增删改方法
查看>>
hdu1698 Just a Hook 线段树:成段替换,总区间求和
查看>>
dorado spring知识补充
查看>>
Android -- ViewPager、Fragment、状态保存、通信
查看>>
如果想消除随机性的感觉
查看>>