CodeForces 161B - Discounts

题意:共有n个物品,k个篮子的,保证每个篮子不为空,当一个篮子里面有stool这个时,这个篮子里面最便宜的东西会打半折,怎样放东西使得所花的钱最少。

1、主要就是贪心的思想,我想的是,要保证所花的钱最少,就应该尽可能使得每个篮子里面有一个stool,但是,这个时候会面临一个问题,如果stool的数目大于或小于k怎么办?当然,小于k的时候,,如果把stool的数目想成是cnt1,那么只要使得cnt1个篮子里面只有一个stool,然后其它篮子里面是pencil就行了,但是大于的情况就不一样了,这个时候我想的是,为了使得总的开销是最小的,那么就需要使得k-1个篮子里面只有一个stool,且要尽可能地把比较大的stool放进篮子里面,这些篮子里就只有一个stool,然后,最后只剩下一个,只需要把所有要买的物品里面花钱最少的那个与这个比较就好了。脑袋有点昏,可能词不达意了,不过我的思路是这样的。

#include <iostream>
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
struct NODE{
    int p,t,id;
}node[1005];
bool comp(NODE a,NODE b)
{
    return a.t==b.t?a.p>b.p:a.t<b.t;
}
int main()
{
   int n,k;
   cin>>n>>k;
   int MIN=0x3f3f3f3f;
   for(int i=1;i<=n;++i)
   {
       cin>>node[i].p>>node[i].t;
       node[i].id=i;
       MIN=min(node[i].p,MIN);
   }
   sort(node+1,node+1+n,comp);
   double sum=0;
   int i=1;
   for(;i<=k-1&&node[i].t==1;++i)
     sum+=(node[i].p*0.5);
   node[k].t==1?sum-=(MIN*0.5):0;
   for(;i<=n;++i)
     sum+=node[i].p;
   printf("%.1lf\n",sum);
   for(int i=1;i<=k-1;++i)
    printf("1 %d\n",node[i].id);
   cout<<n-k+1;
   for(int i=k;i<=n;++i)
     printf(" %d",node[i].id);
   cout<<endl;
   return 0;
}

你可能感兴趣的:(贪心)