NOIP2007 普及组 纪念品分组
发布日期:2021-06-30 16:05:05 浏览次数:3 分类:技术文章

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

第一个方法很容易想到,先将n个数从小到大排序,在后面比较大的数选择一个数+最小的数要<=k,当然要满足贪心的要求,足够的接近k,找到了就删除最小的数和这个数,再继续一样的操作,没有找到就可以直接判断结果了,因为剩下的数都是一个数一组的,但是找数可不能直接一个循环查找,n比较大,时间复杂度n^2肯定超时,除非数据不行,所以一般要线性时间或者nlogn才可以,所以使用二分查找logn时间复杂度,但是还要删除数啊,普通数组删除数比较麻烦,所以使用STL的vector,比较方便。

赋代码:

#include
#include
#include
#include
using namespace std;vector
G;int n,k;void match(int Min){
int r=0; int l=G.size()-1; while(r
>1; if(G[tmp]>Min) { if(l!=tmp) l=tmp; else break; } else { if(r!=tmp) r=tmp; else break; } } if(r
=r;i--) { if(Min>=G[i]) { G.erase(G.begin()+i); return ; } } else { G.erase(G.begin()+r); }} int main(){ scanf("%d%d",&k,&n); for(int i=0;i
k) { cnt++; cnt+=G.size(); break; } match(k-Min); cnt++; } printf("%d\n",cnt); return 0;}

第二个方法,首先以为都是一个数一组,组数=n,再判断最大的数是否可以和最小的的数一个组,不可以就说明,最大的数肯定是单独一个组的,删除最大的数,组数不变,如果可以就删除最大的数和最小的数,组数-1,因为最大的数的组可以删除了。

#include
#include
using namespace std;int n,k;int ans[31000];int main(){
scanf("%d%d",&k,&n); for(int i=0;i

转载地址:https://kaven.blog.csdn.net/article/details/77921360 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:POJ-3723 Conscription
下一篇:TYVJ-P1035 棋盘覆盖

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2024年04月15日 12时18分19秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章