CF 332 C 贪心

题目链接:http://codeforces.com/problemset/problem/332/C

参考  链接: http://blog.csdn.net/cc_again/article/details/9471465

题目意思:

有n个命令,要通过p个,某主席要在通过的p个中选择k个接受。

每个任务有两个值ai,bi, ai表示如果该主席接受该命令,她的头发变灰的数量,bi表示如果该主席不接受该命令时,议员不高兴值。

对于通过的p个命令,该主席要使议员的不高兴值和最小,在相同的情况下,要使自己的头发变灰的数量尽可能的少。

让你求出通过哪p个命令,使得该主席的头发变灰的数量最多,在相同的情况下,输出使议员不高兴最大的选择。

解题思路:

非常关键的一点是主席的想法和我们不同,我们先选出主席一定不会通过的p-k条命令来,那么这p-k条命令必须

unhappy最小,然后那k条必须选的选择num(白头发数量)最多的,这样头发多的选出来了,再更新那不选的p-k条,大致思路

说完了,看代码吧:

/*
题目意思:

有n个命令,要通过p个,某主席要在通过的p个中选择k个接受。

每个任务有两个值ai,bi, ai表示如果该主席接受该命令,她的头发变灰的数量,bi表示如果该主席不接受该命令时,议员不高兴值。

对于通过的p个命令,该主席要使议员的不高兴值和最小,在相同的情况下,要使自己的头发变灰的数量尽可能的少。

让你求出通过哪p个命令,使得该主席的头发变灰的数量最多,在相同的情况下,输出使议员不高兴最大的选择。

*/

//   好难的贪心

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define N 101000

struct stud{
int num,unhappy;
int pos,pp;
}f[N],s[N];

int n,p,k,vis[N];
int ans[N];

int cmp1(stud a,stud b)  //按照主席的习惯,先选不高兴多,然后掉头发也少的
{
    if(a.unhappy==b.unhappy)
        return a.num<b.num;

    return a.unhappy>b.unhappy;
}

int cmp2(stud a,stud b)  //按照我们意愿,选头发掉的多,为什么unhappy大的在前面呢,请看cmp1,unhappy大的在前面,
                          //我们找到前面的unhappy最小的越大,后面掉头发的unhappy的选择越大,
{
     if(a.num==b.num)
       return a.unhappy>b.unhappy;

    return a.num>b.num;
}

int main()
{
    int i;
    while(~scanf("%d%d%d",&n,&p,&k))
    {

       for(i=1;i<=n;i++)
       {
           scanf("%d%d",&f[i].num,&f[i].unhappy);
           f[i].pos=i;
       }

       sort(f+1,f+n+1,cmp1);//按不高兴减序,白头发增序

       memcpy(s,f,sizeof(f));  //请记住,一定要开另一个结构体,不要像我下面的一样,因为cmp2排序后再cmp1可能不是这个序列了

       for(i=1;i<=n;i++)
        f[i].pp=i;

       sort(f+1,f+n-(p-k)+1,cmp2);  //留下最少逼迫主席选前面num大的p-k个(暂时逼迫主席的,后面会更新)

        int j=1;

        for(i=1;i<=k;i++)
        {
            j=max(j,f[i].pp);

            if(i==1)
                printf("%d",f[i].pos);
            else
                printf(" %d",f[i].pos);
        }

        sort(s+j+1,s+n+1,cmp1);

        for(i=j+1;i<=j+p-k;i++)
            printf(" %d",s[i].pos);

        printf("\n");
    }
    return 0;
}

//附上一份让我自己写的吐血的错误代码

   //就是没有开两个数组,wa到死

/*

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 100005

struct stud{
int hair,anger;
int pos,pp;
}f[N];

int n,p,k;

int cmp1(stud a,stud b)
{
    if(a.anger==b.anger)
        return a.hair<b.hair;

    return a.anger>b.anger;
}

int cmp2(stud a,stud b)
{
      if(a.hair==b.hair)
            return a.anger>b.anger;

      return a.hair>b.hair;
}

int main()
{
    int n,i;
    while(~scanf("%d%d%d",&n,&p,&k))
    {
        for(i=1;i<=n;i++)
        {
            scanf("%d%d",&f[i].hair,&f[i].anger);
            f[i].pos=i;
        }

        sort(f+1,f+n+1,cmp1);

        for(i=1;i<=n;i++)
            f[i].pp=i;

        sort(f+1,f+n+1-(p-k),cmp2);

        int j=1;

        for(i=1;i<=k;i++)
           {
            if(i==1)
               printf("%d",f[i].pos);
            else
               printf(" %d",f[i].pos);

            j=max(j,f[i].pp);
           }

         sort(f+1,f+n+1,cmp1);

         sort(f+j+1,f+n+1,cmp1);

         for(i=j+1;i<=j+p-k;i++)
            printf(" %d",f[i].pos);

         printf("\n");
    }

    return 0;
}

*/

CF 332 C 贪心

时间: 2024-10-26 22:59:36

CF 332 C 贪心的相关文章

CF18D 高精度+贪心

http://codeforces.com/problemset/problem/18/D Last year Bob earned by selling memory sticks. During each of n days of his work one of the two following events took place: A customer came to Bob and asked to sell him a 2x MB memory stick. If Bob had s

CF #374 (Div. 2) D. 贪心,优先队列或set

1.CF #374 (Div. 2)   D. Maxim and Array 2.总结:按绝对值最小贪心下去即可 3.题意:对n个数进行+x或-x的k次操作,要使操作之后的n个数乘积最小. (1)优先队列 #include<bits/stdc++.h> #define F(i,a,b) for (int i=a;i<b;i++) #define FF(i,a,b) for (int i=a;i<=b;i++) #define mes(a,b) memset(a,b,sizeof(

CF(437C)The Child and Toy(贪心)

题意:给出一个无向图,每个点有点权,操作是一个一个将所有点揪走直至剩下一个点,揪走一个点的代价是剩下点中与其连边的点的点权和.求完成操作所需花费的最小代价. 解法:贪心的思想,每次将剩余点中点权最大的点揪出,这样可以保证每条边都是会选择相对小的点权被消耗掉.所以直接输出所有边的边权和即可. 代码: /****************************************************** * author:xiefubao **************************

CF 500 C. New Year Book Reading 贪心 简单题

New Year is coming, and Jaehyun decided to read many books during 2015, unlike this year. He has n books numbered by integers from 1 to n. The weight of the i-th (1 ≤ i ≤ n) book is wi. As Jaehyun's house is not large enough to have a bookshelf, he k

CF #401 (Div. 2) E. Hanoi Factory (栈+贪心)

题意:给你一堆汉诺塔的盘子,设内半径为a,设外半径为b,高度为h,如果bj?≤?bi 同时bj?>?ai 我们就认为i盘子能落在在j盘子上,问你最高能落多高 思路:一看题意我们就能想到贪心,首先我们对这些圆盘先按照b从大到小排序,如果b相同,那么就要按照a从大到小排序,其实落汉诺塔的过程就像在栈一样,先进后出,所以我们可以用栈来模拟落汉诺塔的过程,如果当前的不能落上我们就把最上面的盘子拿走,直到能落下一个盘子,每一次都计算一下当前的高度,并判断是否达到最高即可 代码: #include <bi

cf 620C Pearls in a Row(贪心)

d.有一串数字,要把这些数字分成若干连续的段,每段必须至少包含2个相同的数字,怎么分才能分的段数最多? 比如 是1 2 1 3 1 2 1 那么 答案是 21 34 7 即最多分在2段,第一段是1~3,第二段是4~7. 即分成这2段:1 2 1,3 1 2 1 s.很不错的一道贪心的题.当时没怎么细想,后来看了tourist的代码后得知. 可以证明,满足贪心选择性质和最优子结构性质. 贪心策略是:从前向后遍历,每次选择最小长度的符合条件的段. c. #include<iostream> #in

cf 12C Fruits(贪心【简单数学】)

题意: m个水果,n个价格.每种水果只有一个价格. 问如果给每种水果分配价格,使得买的m个水果总价格最小.最大. 输出最小值和最大值. 思路: 贪心. 代码: bool cmp(int a,int b){ return a>b; } string name; map<string,int> mp; int price[200],fruit[200]; int cn; int n,m; int main(){ cin>>n>>m; mp.clear(); cn=0;

CF 626C [Block Towers] 贪心

题目链接:http://codeforces.com/problemset/problem/626/C 题目大意: 有n个人用高度为2的砖往上搭,有m个人用高度为3的砖往上搭.每个人可用的砖块数是无限的,但是要求每个人搭的塔的高度,求所有可行情况中塔的最高高度的最小值. 关键思想:贪心,当且仅当高度为6的倍数时,他们的高度会相同.这时必须有一个人搭更高的,哪个人呢?此时就贪心:另外一种思想是数学的,首先答案x一定是大于等于2n也是大于等于3m的(有6的倍数取等号)对吧,而且m+n<=(x/2+x

cf 540b School Marks 贪心

B. School Marks time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Little Vova studies programming in an elite school. Vova and his classmates are supposed to write n progress tests, for each