1. 程式人生 > >1456 Supermarket 貪心+並查集 /小根堆

1456 Supermarket 貪心+並查集 /小根堆

A supermarket has a set Prod of products on sale. It earns a profit px for each product x∈Prod sold by a deadline dx that is measured as an integral number of time units starting from the moment the sale begins. Each product takes precisely one unit of time for being sold. A selling schedule is an ordered subset of products Sell ≤ Prod such that the selling of each product x∈Sell, according to the ordering of Sell, completes before the deadline dx or just when dx expires. The profit of the selling schedule is Profit(Sell)=Σ x∈Sellpx. An optimal selling schedule is a schedule with a maximum profit. 
For example, consider the products Prod={a,b,c,d} with (pa,da)=(50,2), (pb,db)=(10,1), (pc,dc)=(20,2), and (pd,dd)=(30,1). The possible selling schedules are listed in table 1. For instance, the schedule Sell={d,a} shows that the selling of product d starts at time 0 and ends at time 1, while the selling of product a starts at time 1 and ends at time 2. Each of these products is sold by its deadline. Sell is the optimal schedule and its profit is 80.

Write a program that reads sets of products from an input text file and computes the profit of an optimal selling schedule for each set of products. 
Input 
A set of products starts with an integer 0 <= n <= 10000, which is the number of products in the set, and continues with n pairs pi di of integers, 1 <= pi <= 10000 and 1 <= di <= 10000, that designate the profit and the selling deadline of the i-th product. White spaces can occur freely in input. Input data terminate with an end of file and are guaranteed correct. 
Output 
For each set of products, the program prints on the standard output the profit of an optimal selling schedule for the set. Each result is printed from the beginning of a separate line. 
Sample Input 
4 50 2 10 1 20 2 30 1

7 20 1 2 1 10 3 100 2 8 2 
5 20 50 10 
Sample Output 
80 
185 
Hint 
The sample input contains two product sets. The first set encodes the products from table 1. The second set is for 7 products. The profit of an optimal schedule for these products is 185.

題意:給出N個商品,沒給商品有利潤pi和過期時間di,每天只能賣一個商品,過期商品不可以再賣,求如何安排賣每天的商品使得利潤最大。

思路:

1.並查集:先排序商品的價值從大到小,然後從大到小開始掃描,如果過期那天的前一天沒有的話則安排在那一天。、

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <map>
#include <set>
#include <cmath>
using namespace std;
typedef long long ll;
const int N = 1e4+5;
struct node
{
    int p;
    int d;
}a[N];
int parent[N];
bool cmp(node a,node b)
{
    return a.p>b.p;
}
int ifind(int x)
{
    if(parent[x]==-1)
        return x;
    return parent[x]=ifind(parent[x]);
}
int main()
{
    int n;
    while(scanf("%d",&n)==1){
        memset(parent,-1,sizeof(parent));
        for(int i=0;i<n;i++)
          scanf("%d%d",&a[i].p,&a[i].d);
        sort(a,a+n,cmp);
        int sum=0;
        for(int i=0;i<n;i++){
            int fx=ifind(a[i].d);
            if(fx>0){
                parent[fx]=fx-1;
                sum+=a[i].p;
            }
        }
        printf("%d\n",sum);
    }
    return 0;
}

2.小根堆

貪心:對於每個時間t,我們應該保證在產品不過期的情況下,儘量賣出利潤前t大的商品。

先排序從小到大過期時間,建立一個小根堆(節點權值為利潤),若當前商品的過期時間t等於商品的個數,則說明在之前的安排下前t天已經安排了t個商品賣出,此時,若當前商品的利潤大於堆頂則進行替換。若當前商品的過期時間t大於商品的個數直接插入堆內

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <map>
#include <set>
#include <cmath>
#include <queue>
using namespace std;
typedef long long ll;
const int N = 1e4+5;
struct node
{
    int val;
    int time;
}a[N];
bool cmp(node a,node b)
{
    return a.time<b.time;
}
int main()
{
    int n;
    while(scanf("%d",&n)==1){
        int ans=0;
        priority_queue<int,vector<int>,greater<int> >que;
       for(int i=0;i<n;i++)
            scanf("%d%d",&a[i].val,&a[i].time);
        sort(a,a+n,cmp);
        for(int i=0;i<n;i++){
           if(que.size()<a[i].time){
             que.push(a[i].val);
             ans+=a[i].val;
           }
           else {
             if(que.top()<a[i].val){
                ans-=que.top();
                ans+=a[i].val;
                que.pop();
                que.push(a[i].val);
             }
           }

        }
        cout<<ans<<endl;
    }
    return 0;
}