贪心题整理

水题

1.P1056 排座椅

直通

思路:

  为使得上课时交头接耳的学生的对数最少,所以一条道路需要隔开尽可能多的学生,所以用一个排序就可以搞定

  但是要注意的是,需要按顺序输出!!!!

  这就是10分跟100分的差别!!!

上代码:

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

const int M = 1001;
int m,n,k,l,d;
struct node {
    int id,num;
} col[M],row[M];

int cmp(node a,node b) {
    return a.num > b.num;
}

int cmp2(node a,node b) {
    return a.id < b.id;
}

int main() {
    scanf("%d%d%d%d%d",&m,&n,&k,&l,&d);
    for(int i=1,x,y,x2,y2,cun; i<=d; i++) {
        scanf("%d%d%d%d",&x,&y,&x2,&y2);
        if(x==x2) {
            cun=min(y,y2);
            col[cun].id=cun;
            col[cun].num++;
        }
        else {
            cun=min(x,x2);
            row[cun].id=cun;
            row[cun].num++;
        }
    }
    sort(col+1,col+n+1,cmp);
    sort(row+1,row+m+1,cmp);
    /***********************/
    /*--------重要!--------*/ 
    /*-----一个零的差别-----*/
    sort(col+1,col+l+1,cmp2);
    sort(row+1,row+k+1,cmp2);
    /***********************/
    for(int i=1; i<=k; i++) printf("%d ",row[i].id);
    printf("
");
    for(int i=1; i<=l; i++) printf("%d ",col[i].id);
    return 0;
}
View Code

2.P1208 [USACO1.3]混合牛奶 Mixing Milk

直通

思路:

  从单价最低的开始选,能选多少选多少,典型的贪心嘛~

上代码:

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

int n,m,ans,now,cnt;
struct node {
    int w,pro;
    bool operator < (const node &qwq) const {
        return w < qwq.w;
    }
}a[5005];

int main() {
    scanf("%d%d",&n,&m);
    for(int i=0; i<m; i++) scanf("%d%d",&a[i].w,&a[i].pro);
    sort(a,a+m);
    while(now<n) {
        int tmp=0;
        now+=a[cnt].pro;
        if(now>n) tmp=now-n; //选多了
        ans+=a[cnt].w*(a[cnt].pro-tmp);
        cnt++;
    }
    printf("%d",ans);
    return 0;
}
View Code

3.P1803 凌乱的yyy

直通

思路:

  典型活动安排问题:按照右端点排序,能选就选

坑点:

  会有左端点为0的情况,所以e[i].op>=cur才可以

上代码:

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

const int N = 1000001;
int n,ans;
struct node {
    int op,ed;
    bool operator < (const node &qwq) const {
        return ed < qwq.ed ;
    }
}e[N];

int main() {
    scanf("%d",&n);
    for(int i=0; i<n; i++) scanf("%d%d",&e[i].op,&e[i].ed);
    sort(e,e+n);
    int cur=0;
    for(int i=0; i<n; i++)
        if(e[i].op>=cur) cur=e[i].ed,ans++;
    printf("%d",ans);
    return 0;
}
View Code

4.P1094 纪念品分组

直通

思路:

  先排个序,然后从大的逆序开始选,如果能够组成2人组,那么n--,同时i++,j--;

  如果不能选,直接j--;

  最后输出ans即可

上代码:

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

const int M = 30003;
int w,n,a[M];

int main() {
    scanf("%d%d",&w,&n);
    for(int i=0; i<n; i++) scanf("%d",&a[i]);
    sort(a,a+n);
    int l=0,r=n-1;
    while(l<r) {
        if(a[l]+a[r]<=w) n--,l++,r--;
        else r--;
    }
    printf("%d",n);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zxqxwnngztxx/p/7788409.html