poj 1456
来源:互联网 发布:淘宝运营 数据表格 编辑:程序博客网 时间:2024/06/16 01:37
题目概述
有N个商品,在其保质期dl天内卖掉可得利润v,否则没有利润,卖掉每个商品需要1天,求最大利润
时限
2000ms/6000ms
输入
每组数据第一个整数N,其后N对整数v,dl,输入中空白符会任意出现,输入到EOF为止
限制
1<=N,dl,v<=10000
输出
每行一个数,为所求最大利润
样例输入
4
50 2
10 1
20 2
30 1
7
20 1
2 1
10 3
100 2
8 2
5 20
50 10
3
1 1
100 2
100 2
2
99 1
100 100
样例输出
80
185
200
199
讨论
贪心,对于那些贵的商品,都希望其能在保质期内尽量晚的卖掉,但是无法避免有些由于太便宜而被扔掉,那么每次取最贵的,从保质期这天开始(当然也包括这一天)向前找空闲的一天,将之安排在这一天卖掉,由于已经按利润降序排,故后安排的肯定不如先安排的贵,因而若没找到空闲时间就直接扔掉了,然而从实现层面上,由于需要处理if语句,导致效率受到一定影响,采用优化后的并查集可以进一步加快速度
并查集,基本思想也是继承上面的,但是以并查集表示每一天,如果这天已经安排了,就以前一天为父节点,这样查找时总能找到空闲的一天,如果找到的是第0天,扔掉,这样就避开了很多if语句的处理,从实现层面上,初始化并查集时也不用全初始化,只要把保质期最长的那一天及之前都初始化就可以了
另外uva上也有这个题,但是下面两种方法都会超时
题解装填
贪心:284K,141MS,C++,723B
并查集:284K,63MS,C++,875B
题解代码
贪心:
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define INF 0x3f3f3f3f#define MAXN 10004#define memset0(a) memset(a,0,sizeof(a))struct It//每个商品的结构{ int v, dl;//value 利润 deadline 保质期 bool operator<(const It &b)const { return v > b.v; }}its[MAXN];int N;//商品总数int schedule[MAXN];//每天安排销售的商品的利润int fun(){ for (int p = 0; p < N; p++) scanf("%d%d", &its[p].v, &its[p].dl);//input sort(its, its + N); int sum = 0; for (int p = 0; p < N; p++) for (int i = its[p].dl; i; i--)//从保质期最后一天枚举 if (!schedule[i]) {//找到空白的一天 题目保证每个商品利润都是正 sum += schedule[i] = its[p].v; break; } return sum;}int main(void){ //freopen("vs_cin.txt", "r", stdin); //freopen("vs_cout.txt", "w", stdout); while (~scanf("%d", &N)) {//input printf("%d\n", fun());//output memset0(schedule); }}
并查集:
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define INF 0x3f3f3f3f#define MAXN 10004#define memset0(a) memset(a,0,sizeof(a))struct It{ int v, dl; bool operator<(const It &b)const { return v > b.v; }}its[MAXN];int N;int id[MAXN];//父节点int UFfind(int a){ int p = a; while (a != id[a]) a = id[a]; return id[p] = a;}int fun(){ int longest = -INF;//最长的保质期 for (int p = 0; p < N; p++) { scanf("%d%d", &its[p].v, &its[p].dl);//input longest = max(longest, its[p].dl); } sort(its, its + N); for (int p = 0; p <= longest; p++)//初始化并查集 id[p] = p; int sum = 0, available;//总利润 空闲的一天 for (int p = 0; p < N; p++) if (available = UFfind(its[p].dl)) {//找到的是第0天就扔掉了 sum += its[p].v; id[available]--;//这天已被占用 连到前一天 } return sum;}int main(void){ //freopen("vs_cin.txt", "r", stdin); //freopen("vs_cout.txt", "w", stdout); while (~scanf("%d", &N))//input printf("%d\n", fun());//output}
EOF
0 0
- poj 1456
- poj 1456
- POJ 1456
- poj 1456
- POJ 1456
- POJ 1456
- poj 1456 supermarket
- POJ-1456 Supermarket【贪心】
- poj 1456 Supermarket
- Supermarket poj 1456
- POJ 1456 Supermarket
- POJ 1456 Supermarket
- POJ-1456-Supermarket
- poj 1456 Supermarket
- poj 1456 Supermarket
- POJ - 1456 Supermarket
- poj 1456 DP
- POJ 1456 Supermarket
- 【第一行代码-Android】学习(一)及在studio的迁移(5)存储数据
- UE4下的某些保密字段的加密处理
- poj3239 n皇后问题快速得到一个解
- wget: command not found
- [Unity] Unity5.4 build iOS的时候把Plugins/Android也打进去了
- poj 1456
- jq复选框的判断
- 909422229__正则表达式简介
- JAVA 多态 由浅及深介绍
- Java中的多线程
- JAVA语言工具类封装-基于poi的excel导出功能
- 2016年-年终总结-回顾历史,展望未来
- android java运行堆栈显示
- 知识梳理------进程(一)