HHTC_学校集训编程题目(4)(贪心)

HHTC_学校集训编程题目(4)(贪心)

Cleaning Shifts

Farmer John is assigning some of his N (1 <= N <= 25,000) cows to do some cleaning chores around the barn. He always wants to have one cow working on cleaning things up and has divided the day into T shifts (1 <= T <= 1,000,000), the first being shift 1 and the last being shift T.

Each cow is only available at some interval of times during the day for work on cleaning. Any cow that is selected for cleaning duty will work for the entirety of her interval.

Your job is to help Farmer John assign some cows to shifts so that (i) every shift has at least one cow assigned to it, and (ii) as few cows as possible are involved in cleaning. If it is not possible to assign a cow to each shift, print -1.

Input

Line 1: Two space-separated integers: N and T

Lines 2…N+1: Each line contains the start and end times of the interval during which a cow can work. A cow starts work at the start time and finishes after the end time.

Output

Line 1: The minimum number of cows Farmer John needs to hire or -1 if it is not possible to assign a cow to each shift.

Sample Input

3 10
1 7
3 6
6 10

Sample Output

2

Hint

This problem has huge input data,use scanf() instead of cin to read data to avoid time limit exceed.

INPUT DETAILS:

There are 3 cows and 10 shifts. Cow #1 can work shifts 1…7, cow #2 can work shifts 3…6, and cow #3 can work shifts 6…10.

OUTPUT DETAILS:

By selecting cows #1 and #3, all shifts are covered. There is no way to cover all the shifts using fewer than 2 cows.

题意大约就是一个区域覆盖问题~
就是求用最少的区间数覆盖全部区间~
经典的贪心问题~
举个例子:
在这里插入图片描述
思路:
在这里插入图片描述
解题方法:
在这里插入图片描述
AC代码:

#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <cmath>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;

int N,T;

struct Interval{
    int start, end;
}a[25005];

bool cmp(Interval a, Interval b)
{
    if(a.start == b.start)
        return a.end > b.end;
    else
        return a.start < b.start;
}

void solve(){
    int sum = 0;
    int index = 0;
    int ok = 1;
    int s=0,e=0;
    while(e < T){
        s = e + 1;
        for(int i = index; i < N; i++){
            if(a[i].start <= s){
                if(a[i].end >= s){
                    e = max(e,a[i].end);
                }
            }else{
                index = i;
                break;
            }
        }
        if(s > e){
            break;
        }else{
            sum++;
        }
    }
    if(e == T){
        printf("%d\n",sum);
    }else{
        printf("-1\n");
    }
}

int main()
{
    int start = 0;
    int end = 0;
    scanf("%d%d",&N,&T);
    for(int i=0; i<N; i++){
        scanf("%d%d",&a[i].start, &a[i].end);
        if(a[i].start == 1) start = 1;
        if(a[i].end == T) end = 1;
    }
    if(start == 0 || end == 0){
        printf("-1\n");
        return 0;
    }
    sort(a,a+N,cmp);
    solve();
    return 0;
}

Design T-Shirt

Soon after he decided to design a T-shirt for our Algorithm Board on Free-City BBS, XKA found that he was trapped by all kinds of suggestions from everyone on the board. It is indeed a mission-impossible to have everybody perfectly satisfied. So he took a poll to collect people’s opinions. Here are what he obtained: N people voted for M design elements (such as the ACM-ICPC logo, big names in computer science, well-known graphs, etc.). Everyone assigned each element a number of satisfaction. However, XKA can only put K (<=M) elements into his design. He needs you to pick for him the K elements such that the total number of satisfaction is maximized.

Input

The input consists of multiple test cases. For each case, the first line contains three positive integers N, M and K where N is the number of people, M is the number of design elements, and K is the number of elements XKA will put into his design. Then N lines follow, each contains M numbers. The j-th number in the i-th line represents the i-th person’s satisfaction on the j-th element.

Output

For each test case, print in one line the indices of the K elements you would suggest XKA to take into consideration so that the total number of satisfaction is maximized. If there are more than one solutions, you must output the one with minimal indices. The indices start from 1 and must be printed in non-increasing order. There must be exactly one space between two adjacent indices, and no extra space at the end of the line.

Sample Input

3 6 4
2 2.5 5 1 3 4
5 1 3.5 2 2 2
1 1 1 1 1 10
3 3 2
1 2 3
2 3 1
3 1 2

Sample Output

6 5 3 1
2 1

思路:
比较每一列和的大小,按照从大到小排序
如果大小一样,则按照id从小到大排序
然后在输入输出的时候注意,输入的数是double型
输出时需要按照id的从大到小输出~
AC代码:

#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <cmath>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;

int id[10005];

struct node{
    int id;
    double sum;
}a[10005];

bool cmp(node a,node b){
    if(a.sum != b.sum)
        return a.sum>b.sum;
    else
        return a.id<b.id;
}

bool cmp2(int a,int b){
    return a>b;
}

int main()
{
    int n,m,k;
    while(cin>>n>>m>>k){
        memset(a,0,sizeof(a));
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                double x;
                cin>>x;
                a[j].id = j+1;
                a[j].sum += x;
            }
        }
        sort(a,a+m,cmp);
        for(int i=0;i<k;i++){
            id[i] = a[i].id;
        }
        sort(id,id+k,cmp2);
        for(int i=0;i<k;i++){
            if(i == k-1)
                cout<<id[i]<<endl;
            else
                cout<<id[i]<<" ";
        }
    }
    return 0;
}

A Minimum Land Price

这道题题目给出的是PDF形式~
在这里插入图片描述
就是一最低的价格购买土地,而价格会按照指数的形式增长~
就是公式写的那样,所以我们要先把贵的土地给先买了,这样就是最便宜的~
AC代码:

#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <cmath>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;

long long id[10005];

bool cmp(long long a,long long b){
    return a > b;
}

int main()
{
    int T;
    cin>>T;
    while(T--){
        int k =0;
        for(int i=0;;i++){
            cin>>id[i];
            if(id[i] == 0)
                break;
            k++;
        }
        sort(id,id+k,cmp);
        long long sum =0;
        for(int i=0;i<k;i++){
            long long num = 2;
            for(int j=0;j<i+1;j++){
                num *= id[i];
            }
            sum += num;
        }
        if(sum > 5000000)
            cout<<"Too expensive"<<endl;
        else
            cout<<sum<<endl;
    }
    return 0;
}

Doing Homework again

Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot of homework to do. Every teacher gives him a deadline of handing in the homework. If Ignatius hands in the homework after the deadline, the teacher will reduce his score of the final test. And now we assume that doing everyone homework always takes one day. So Ignatius wants you to help him to arrange the order of doing homework to minimize the reduced score.

Input

The input contains several test cases. The first line of the input is a single integer T that is the number of test cases. T test cases follow.
Each test case start with a positive integer N(1<=N<=1000) which indicate the number of homework… Then 2 lines follow. The first line contains N integers that indicate the deadlines of the subjects, and the next line contains N integers that indicate the reduced scores.

Output

For each test case, you should output the smallest total reduced score, one line per test case.

Sample Input

3
3
3 3 3
10 5 1
3
1 3 1
6 2 3
7
1 4 6 4 2 4 3
3 2 1 7 6 5 4

Sample Output

0
3
5

本题考察的的是贪心问题,要想减得分数最少,
先找做分数最多的,因为都是在一天之内做完
若分数相同,则先做时间最早的,这样才能损失的最少
AC代码:

#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <cmath>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;

struct node{
    int time,score;
}d[100005];

bool cmp(node a,node b){
    if(a.score == b.score)
        return a.time < b.time;
    else
        return a.score > b.score;
}

int vis[100005];

int main()
{
    int T;
    cin>>T;
    while(T--){
        memset(vis,0,sizeof(vis));
        int n;
        cin>>n;
        int sum = 0;
        for(int i=0;i<n;i++)
            cin>>d[i].time;
        for(int i=0;i<n;i++)
            cin>>d[i].score;
        sort(d,d+n,cmp);
        for(int i=0;i<n;i++){
            int j;
            for(j = d[i].time; j>0; j--){
                if(vis[j] == 0){
                    vis[j] = 1;
                    break;
                }
            }
            if(j == 0)
                sum += d[i].score;
        }
        cout<<sum<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值