POJ 1456(贪心,并查集)

Supermarket
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 21651   Accepted: 9579

Description

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

题目大意是买卖N件东西,每件东西都有个截止时间,在截止时间之前买都可以,而每个单位时间只能买一件。问最大获利。

这题数据比较弱,贪心按照价格排序,遍历每个物品,当前的物品的期限day,遍历day到1(从后往前遍历怎么择后而选),如果找到一天可以卖这个物品,就对这天进行标记,ans加上这个物品的价值

/*直接贪心的代码*/
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <iomanip>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <vector>
//const int maxn = 1e5+5;
#define ll long long
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}

#define MAX INT_MAX
#define FOR(i,a,b) for( int i = a;i <= b;++i)
#define bug cout<<"--------------"<<endl
using namespace std;
int n;
struct node
{
    int v,t;

}a[11000];
bool cmp(node a,node b)
{
    return a.v > b.v;
}
int vis[11000];

int main()
{
    while(scanf("%d",&n) != EOF)
    {
        int ans = 0;
        memset(vis,0,sizeof(vis));
        FOR(i,1,n)
        {
            cin>>a[i].v>>a[i].t;
        }
        sort(a+1,a+n+1,cmp);

        for(int i=1;i<=n;++i)
        {
            int temp = a[i].t;
            while(vis[temp] !=0 && temp >= 1) temp -- ;

            if(temp == 0) continue;
            if(temp != 0 )
            {
                ans += a[i].v;
                vis[temp] = 1;
            }

        }
        cout<<ans<<endl;

    }

}

并查集的话主题思想也是贪心,只是标记这天的方法,改用并查集状态压缩,数据弱,优化的不明显

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <iomanip>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <vector>
//const int maxn = 1e5+5;
#define ll long long
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}

#define MAX INT_MAX
#define FOR(i,a,b) for( int i = a;i <= b;++i)
#define bug cout<<"--------------"<<endl
using namespace std;
const int N = 1e5+5;
int n;
int pre[N];
struct node
{
    int v,t;

}a[11000];
bool cmp(node a,node b)
{
    return a.v > b.v;
}
int Find(int x)
{
    if(pre[x] == x) return x;
    return  pre[x] = Find(pre[x]);
}

int main()
{
    while(scanf("%d",&n) != EOF)
    {
        FOR(i,0,N-1) pre[i] = i;

        int ans = 0;
        FOR(i,1,n)
        {
            cin>>a[i].v>>a[i].t;
        }
        sort(a+1,a+n+1,cmp);

        for(int i=1;i<=n;++i)
        {
            int day = Find(a[i].t);
            if(day == 0) continue;
            pre[day] = day - 1;
            ans += a[i].v;
        }
        cout<<ans<<endl;

    }

}

 





题目大意是买卖N件东西,每件东西都有个截止时间,在截止时间之前买都可以,而每个单位时间只能买一件。问最大获利。

posted @ 2019-08-22 15:22  阿斯水生产线  阅读(220)  评论(0编辑  收藏  举报