557C - Arthur and Table (前缀和)
2015-07-26 13:35
211 查看
如果选择L为最后的最长长度,那么大于L的桌腿必须全去除。然后假如此时剩下M条桌腿,长度L的桌腿有num[L]条,如果tmp=num[L]*2-1-M<=0就不需要再去除,如果tmp>0,就需要在小于L的腿中选择tmp条花费最小的桌腿。
首先把桌腿按长度排序然后预处理前缀和,这样后可以O(1)得到大于L的桌腿的总代价。
然后因为代价的最大值才200,那么维护小于L的每种代价桌腿的数量,按照计数排序的方法选择桌腿去除,再维护这个数量。
代码:
首先把桌腿按长度排序然后预处理前缀和,这样后可以O(1)得到大于L的桌腿的总代价。
然后因为代价的最大值才200,那么维护小于L的每种代价桌腿的数量,按照计数排序的方法选择桌腿去除,再维护这个数量。
代码:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #include <algorithm> int N; struct node{ int l,d; }G[100005]; int num[100005]; int c[100005]; int n[100005]; int D[205]; bool cmp(node a,node b){ if(a.l==b.l) return a.d<b.d; return a.l<b.l; } int main(){ scanf("%d",&N); for(int i=0;i<N;i++){ scanf("%d",&G[i].l); num[G[i].l]++; } for(int i=0;i<N;i++){ scanf("%d",&G[i].d); } sort(G,G+N,cmp); c[0]=G[0].d; for(int i=1;i<N;i++){ c[i]=c[i-1]+G[i].d; } n[0]=0; for(int i=1;i<=100000;i++){ n[i]=n[i-1]+num[i]; } int res=100000000; for(int i=1;i<=100000;i++){ if(!num[i]) continue; int cur=c[N-1]-c[n[i]-1]; int tmp=n[i]-(num[i]*2-1); while(tmp>0){ for(int i=1;i<=200;i++){ if(D[i]<=tmp){ cur+=D[i]*i; tmp-=D[i]; } else if(tmp<D[i]){ cur+=tmp*i; tmp=0; } } } res=min(res,cur); for(int j=n[i-1];j<n[i];j++){ D[G[j].d]++; } } printf("%d\n",res); return 0; }
相关文章推荐
- <互联网产品>如何看待一个产品是好还是不好?
- 【2015/07/26】实习实战2--基础小知识
- BestCoder 1st Anniversary ($) 第三题 Sequence
- JBPM4实例教程
- springmvc+mybatis+mysql整合实战
- cocos2d-x 颜色
- yii组态 redis主从配置(随着代码)
- 九宫格
- rtp对h264 nalu fu-a的处理
- hdu 1402 A * B Problem Plus 快速傅里叶变换
- poj 1789 Truck History(kruskal算法)
- eclipse修改java代码后报错: java.lang.OutOfMemoryError: PermGen space
- apache + tomcat动静分离配置
- GTK入门学习:布局容器之固定布局
- 视频播放
- 建造者模式
- C++ 代码换行
- leetcode:Factorial Trailing Zeroes
- Objective-C通过联合存储为类增加属性及原理解析
- 线程间通信