POJ 1456 Supermarket

来源:互联网 发布:科比生涯数据图 编辑:程序博客网 时间:2024/06/04 19:15

VJ题目地址

题意:n种商品,每种都有一个限定卖出的时间,如果在限定时间内没有卖出,则无法再卖出。每个单位时间内,只允许卖出一件商品。求给出的这组商品利润最高多少。

解题思路是用并查集来处理区间,这题的区间是卖出时间的限制。

首先取得最大的商品时间,然后在这个最大区间内,初始化dad数组,使每个时间都指向自己,这表明这个时间没有被使用。

当这个时间有商品卖出时,则需要把这个时间 t 指向 t-1 这表明,这个时间已经被使用了,接下来如果有限定时间为 t 的商品,那么它最多也只能在t-1那个时间卖出,因为时间只能往前推。

以上保证了一定在合法时间内卖出商品,那么如何保证最后的利润最高?

直接按商品价格从高到低排序,每次取利润最高的出来,判断下这个商品在限定时间内可不可以被卖出即可。

以题目中的第二个测试用例举例:

20 1 ||  2 1||  10 3 || 100 2||  8 2 ||  5 20 ||  50 10  首先排序---> 100 2 || 50 10 || 20 1 || 10 3 || 8 2 || 5 20 || 2 1

1.拿到100 此时 dad[2]=2可用,那么res+100,变更dad[2]=1        res=100

2.拿到50   此时 dad[10]=10可用,那么res+50,变更dad[10]=9    res=150

3.拿到20   此时 dad[1]=1可用,那么res+20,变更dad[1]=0    res=170

4.拿到10   此时dad[3]=3可用,那么res+10,变更dad[3]=2          res=180

5.拿到8     此时dad[2]=1   dad[1]=0说明2之前的时间都用完了 因此不可用

6.拿到5     此时dad[20]=20可用,那么res+5,变更dad[20]=19         res=185 

7.拿到2     此时dad[1]=0 说明1之前的时间都用完了 因此不可用

最后得到结果res=185


以上就是用并查集的思想来管理区间问题的过程

代码:

import java.util.Arrays;import java.util.Scanner;class Prod implements Comparable<Prod>{int p,t;public Prod(int p, int t) {this.p = p;this.t = t;}@Overridepublic int compareTo(Prod o) {return o.p-this.p;}}public class Main {static Scanner sc=new Scanner(System.in);static int n,max,res;static int dad[]=new int[10010];static Prod [] p=new Prod[10010];static void init(){for(int i=0;i<=max;i++){dad[i]=i;}}static int find(int x){if(x==dad[x]) return x;else{dad[x]=find(dad[x]);return dad[x];}}public static void main(String[] args) {while(sc.hasNext()){n=sc.nextInt();max=0;res=0;for(int i=0;i<n;i++){p[i]=new Prod(sc.nextInt(),sc.nextInt());max=Math.max(max,p[i].t);}Arrays.sort(p, 0, n);init();int tmpd;for(int i=0;i<n;i++){tmpd=find(p[i].t);if(tmpd>0){res+=p[i].p;dad[tmpd]=tmpd-1;}}System.out.println(res);}}}



当然本身这题最明显的是贪心思想,并查集只是拿来优化,纯贪心应该是可以A的。

原创粉丝点击