AcWing 防晒

AcWing 防晒

Description

  • 有C头奶牛进行日光浴,第i头奶牛需要minSPF[i]到maxSPF[i]单位强度之间的阳光。

    每头奶牛在日光浴前必须涂防晒霜,防晒霜有L种,涂上第i种之后,身体接收到的阳光强度就会稳定为SPF[i],第i种防晒霜有cover[i]瓶。

    求最多可以满足多少头奶牛进行日光浴。

Input

  • 第一行输入整数C和L。

    接下来的C行,按次序每行输入一头牛的minSPF和maxSPF值,即第i行输入minSPF[i]和maxSPF[i]。

    再接下来的L行,按次序每行输入一种防晒霜的SPF和cover值,即第i行输入SPF[i]和cover[i]。

    每行的数据之间用空格隔开。

Output

  • 输出一个整数,代表最多可以满足奶牛日光浴的奶牛数目。

Data Size

  • 1≤C,L≤2500,
    1≤minSPF≤maxSPF≤1000,
    1≤SPF≤1000

Sample Input

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

Sample Output

2

题解:

  • 贪心。
  • 首先这道题可以想到二分图匹配吧。把奶牛看做一个集合,防晒霜看做一个集合,用匈牙利求最大匹配。理论上是可行的。但是匈牙利的复杂度是O(nm),n是2500可以接受,但是对于此题m可能有很大很大啊(因为一种防晒霜可以有多瓶)。所以考虑换算法。
  • 贪心?怎么想到的?
  • 按照maxSPF递增的顺序排序,依次考虑每头奶牛。
  • 对于每头奶牛,在她能用的防晒霜里选SPF最小的用。为什么?用“微扰法”证明:对于当前奶牛能用的防晒霜x, y,那么后面一头奶牛会出现3种情况
  1. x, y她也都可以用
  2. x, y她都不能用
  3. x她用不了,但y她可以用
  • 可以看出,不管哪一种情况,给当前奶牛用x都是最优的。所以这是一个正确的贪心策略。复杂度是O(nm),在这里m就变成了定值。因为用了cnt来计数。
  • 可以用二分优化成O(nlogn),我就懒没写了。
  • 可能二分图我写的常数巨大,导致过不了。还请大大们帮看看是哪里还可以优化。
//贪心
#include 
#include 
#include 
#define N 2505
using namespace std;

struct B {int val, cnt;} b[N];
struct A {int x, y;} a[N];
int n, m, ans;

bool cmp1(A u, A v) {return u.y < v.y;}
bool cmp2(B u, B v) {return u.val < v.val;}

int main()
{
    freopen("A110.in", "r", stdin);
    freopen("A110.out", "w", stdout);
    
    cin >> n >> m;
    for(int i = 1; i <= n; i++) scanf("%d%d", &a[i].x, &a[i].y);
    for(int i = 1; i <= m; i++) scanf("%d%d", &b[i].val, &b[i].cnt);
    sort(a + 1, a + 1 + n, cmp1), sort(b + 1,b + 1 + m, cmp2);
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            if(b[j].cnt && a[i].x <= b[j].val && b[j].val <= a[i].y)
                {b[j].cnt--, ans++; break;}
    cout << ans;
    return 0;
}
//二分图
#include 
#include 
#include 
#include 
#define N 100005
using namespace std;

struct A {int x, y;} a[N];
int n, m, g, ans;
int mat[N], b[N];
bool vis[N];

bool dfs(int p)
{
    for(int i = 1; i <= m; i++)
        if(a[p].x <= b[i] && b[i] <= a[p].y && !vis[i])
        {
            vis[i] = 1;
            if(!mat[i] || dfs(mat[i]))
            {
                mat[i] = p;
                return 1;
            }
        }
    return 0;
}

int main()
{
    freopen("A110.in", "r", stdin);
    freopen("A110.out", "w", stdout);
    
    cin >> n >> m;
    for(int i = 1; i <= n; i++) scanf("%d%d", &a[i].x, &a[i].y);
    for(int i = 1; i <= m; i++)
    {
        int val, cnt;
        scanf("%d%d", &val, &cnt);
        for(int j = 1; j <= cnt; j++) b[++g] = val;
    }
    m = g;
    for(int i = 1; i <= n; i++)
    {
        memset(vis, 0, sizeof(vis));
        if(dfs(i)) ans++;
    }
    cout << ans;
    return 0;
}

转载于:https://www.cnblogs.com/BigYellowDog/p/11280573.html

你可能感兴趣的:(AcWing 防晒)