纪念品分组java_纪念品分组 (C++代码)

解题思路:

注意事项:

参考代码:

本题思路:比较经典的贪心,读入之后快排,定义两个指针z,y(其实就是两个变量QAQ),分别从0和n-1开始,如果左侧的小数加上右侧的大数比规定范围w小,就把它们俩分在一组,ans++,z++,y--,不然就把右侧的数单独分在一组,ans++,y--,最后输出ans

#include#include#include//sort必备万能头文件using namespace std;int a[1000000],ans;//定义(这里插一句,本人喜欢把数组和最后结果放在函数外定义,这样使它们的初值默认为0,不容易犯没有初始化的错误)int main(){//过程华丽开始

int n,w;//定义

scanf("%d",&w);//读入

scanf("%d",&n);//读入

for(int i=0;i

sort(a,a+n);//调用快排函数sort

int z=0,y=n-1;//定义指针(变量)

while(z<=y){//开始主要的处理

if(a[z]+a[y]<=w){ans++;z++;y--;}//如果能装下,就装

else {y--;ans++;}//不能装下,将大的分为单独的一组

}    printf("%d\n",ans);//输出

return 0;//过程完美结束}

评论

还没有评论

评论

作者: Aeber 更新时间: 2017-10-30 20:34  在Ta的博客查看  2

蒟蒻什么算法都没学过,但是了解过贪心的思路

用了一个数组一个布尔量数组,思路是排序后从最贵的开始查看,

如果和最便宜的相加后符合条件则计数++标记马克上,

便宜的下标符合条件后再往上,但贵的无论是否单独一组都只看一遍

最后检查一遍,没有马克过的数据就是单独一组,计数++

好处就是小白都能看懂

#include#includeusing namespace std;bool judge(int a,int i,int n){    if (i+a<=n)        return true;    else return false;

}//闲着没事干写了个函数

int main(){    int max_price,num;    cin>>max_price>>(num);    bool check[num+1];    int item[num+1];//一个数组一个布尔量数组

for (int i=1;i<=num;i++)

{        cin>>item[i];

check[i]=true;//为了方便写成这样,其实是没有分组

}

sort (item+1,item+num+1);    int m=1,ans=0;    for (int i=num;i>0;i--)

{        if (check[i]==false) continue;//如果这个商品已经被拿过,直接跳过

//其实可以用break

if (judge(item[i],item[m],max_price))

{

check[i]=false;

check[m]=false;//马克两件已分组奖品

m++;//便宜下标++;

ans++;//计数++

}

}    for (int i=1;i<=num;i++)        if (check[i]) ans++;//检查单独一组

cout<

}

评论

还没有评论

评论

作者: xukuan 更新时间: 2017-10-26 13:10  在Ta的博客查看  2

贪心,递归,排序

if a[i]+a[j]

else ...

.pas

var

w,n,i,j,t,count:longint;

a:array[0..30010] of longint;procedure qsort(var a:array of longint; l,r:longint);//快速排序

var

i,j,x,tmp:longint; begin

i:=l; j:=r; x:=a[(i+j) div 2];  repeat

while a[i]x do dec(j);   if i<=j then

begin

if i<>j then

begin

tmp:=a[i];

a[i]:=a[j];

a[j]:=tmp;      end;

inc(i);

dec(j);    end;  until i>j;  if l

readln(w);

readln(n); for i:=1 to n do

readln(a[i]);

qsort(a,1,n);

i:=n; j:=1; while i>=j do

begin

if a[i]+a[j]<=w then//可以放两个

begin

dec(i);

inc(j);    end

else dec(i);//不能放两个

inc(count);//计数器加一

end;

writeln(count);end.

评论

还没有评论

评论

作者: liuliming6772 更新时间: 2017-10-08 09:00  在Ta的博客查看  1

这道题是一个贪心题,看楼下的各位大佬、大神们,在用桶排和标记来写,蒟蒻在万分景仰膜拜之余,也深感难以理解,所以发下自己的思路。

读入之后先用sort排序,然后用两个指针一起向中间走,每次选择都尽可能的让当前状态下最大的和最小的分在一组,如果不行就最大的单独分一组,这样贪心下来就是最少分的组了。证明如下:

如果最大的a[r]不与最小的a[l]分在一组,而是a[r]与a[i]在一组,a[l]与a[j]在一组,因为a[l]<=a[i]&&a[r]>=a[j],所以交换两者分组不影响后续选择,而a[r]如果不能与a[l]在一组,因为a[l]为当前最小值,所以a[r]只能单独为一组,所以贪心是 正确的。

#includeusing namespace std;int W,ans=0;int n,a[30001];int l,r,i;int main(){    scanf("%d%d",&W,&n);    for(i=1;i<=n;i++)      scanf("%d",&a[i]);

sort(a+1,a+n+1);

l=1;  r=n;    while(l<=r)//一定要有等号。

{        if(a[l]+a[r]<=W)   //一定要有等号。

l++,r--,ans++;        else

r--,ans++;   //贪心过程

}    printf("%d",ans);    return 0;

}

评论

chengdadao

算法速度快,落谷能过。但i>=5,j>=5貌似有点问题。 100 3 90 3 3 的数据好像是错误结果。

评论

作者: 你好帅_56 更新时间: 2017-10-02 20:04  在Ta的博客查看  0

在此放一个比较简洁易懂的桶排序,因为每组最多只能包括两件纪念品,所以其实模拟一下发现无需排序,同时我们发现w范围很小,因此桶排序还能缩小循环范围。

#include#include#includeusing namespace std;int x,n,w,p[201],num;int main(){    cin>>w>>n;    for(int i=1;i<=n;i++)

{        scanf("%d",&x);

p[x]++;

}    for(int i=200;i>=5;i--)

{        while(p[i])

{

num++;

p[i]--;            for(int j=w-i;j>=5;j--)//贪心,找到能装的最大的放进来;

{                if(p[j])

{

p[j]--;                    break;//只能装2个;

}

}

}

}    cout<

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值