POJ 1456
描述
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.
4 50 2 10 1 20 2 30 1 7 20 1 2 1 10 3 100 2 8 2 5 20 50 10
80 185
Southeastern Europe 2003
题意大概是这样的
对于每个商品, 给出它的价值和它的截止时间, 只有在截止时间结束之前把商品卖掉才可以收获相应的价值
那么如何合理的安排天数才能够使得利益最大化
这个明显是一道贪心的问题,我的做法很简单,将物品按照价值从小到大排序,然后对于价值高的物品优先安排,看其能不能放到它的ddl那天,如果不能放到ddl那天,说明被占用的天被用来卖价值更高的物品了,那么我们就从ddl倒着向前找,找到没有被占用的一天把它占用掉
代码如下,PS今天懒得看并查集,网上的题解说可以用并查集优化,即不是一个个向前找,直接找一下pre就可以在o(1)的时间内找到可以用的天数
反正懒得写了
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<memory.h>
using namespace std;
int n;
struct node
{
int val, ddl;
bool operator < (const node & n1)
{
return val > n1.val;
}
}p[10010];
bool d[10010];
int main()
{
while (cin >> n)
{
long res = 0;
for (int i = 0; i < n; i++)
scanf("%d %d", &p[i].val, &p[i].ddl);
sort(p, p + n);
memset(d, true, sizeof(d));
for (int i = 0; i < n; i++)
{
if (d[p[i].ddl])
{
d[p[i].ddl] = false;
res += p[i].val;
}
else
{
for (int j = p[i].ddl - 1; j > 0; j--)
{
if (d[j])
{
d[j] = false;
res += p[i].val;
break;
}
}
}
}
printf("%d\n",res);//cout << res << endl;
}
return 0;
}