hdu 1789(贪心算法、自定义排序(Comparable))

再次做作业

求解方法 贪心算法
知识点 贪心算法、自定义排序、自定义类(特殊)输入
解题思路(完整AC代码再在最下方):
1.贪心点分析:
  对于所有的作业,按照分数从高到低排序,分数相同时,截止时间小的排在前面。另外初始化一个大小为 [1005] 的数组,用来保存某一天是否已经被占用 (排序可以采用Comparator或Comparable实现,许多题解采用Comparator实现,本文介绍采用Comparable实现的方法)。

  • 然后开始贪心,对于每份作业,看从当天到当前之前的时间里面,有没有空余,
  • 如果有空余,安排到空余且天数最大的一天;
  • 如果没有空余,这份作业只能被扣分。

    2.自定义Comparable排序:
      直接将自定义类实现Comparable接口,并实现其中的compareTo方法,按照自己定义的排列顺序将不同属性定义为不同级别的升降序排列,在排序时直接使用Collections或Arrays的sort方法将集合或数组传入即可(示例):
class Node implements Comparable<Node>{
	public int d;
	public int c;	
	public Node(int d) {
		this.d=d;
	}
	@Override
	public int compareTo(Node node) {
		// TODO 自动生成的方法存根
		//分数降序,天数升序排列
		if(this.c!=node.c) {
			return node.c-this.c;	//降序:别人的减去自家的
		}
		else {
			return this.d-node.d;	//升序:自家的减去别人的
		}
	}

}

3.特殊自定义结点输入:
  当题目要求一次性输入自定义节点的某一个属性时(本题),可以采用如下的方法(在结点中定义某一个属性的构造方法方法,另一个属性再通过赋值的方法给予值):

List<Node> list=new ArrayList<Node>();
			for(int i=0;i<n;i++) {
				list.add(new Node(sc.nextInt()));		
			}
			for(int i=0;i<n;i++) {
				list.get(i).c=sc.nextInt();
			}	

			Collections.sort(list);	//	直接排序

问题描述:
  Ignatius刚从第30届ACM / ICPC重返校园。现在,他有很多作业要做。每个老师都给他交作业的最后期限。如果Ignatius在截止日期之后交作业,则老师会降低其最终考试的分数。现在,我们假设每个人都要花一天的功课。因此,伊格纳修斯(Ignatius)希望您帮助他安排功课的顺序,以最大程度地降低分数。
输入:
  输入包含几个测试用例。输入的第一行是单个整数T,它是测试用例的数量。随后是T测试用例。
  每个测试用例都以一个正整数N(1 <= N <= 1000)开头,该正整数表示作业的数量。然后跟随两行。第一行包含N个整数,它们指示受试者的截止日期,而第二行包含N个整数,指示分数的降低。

输出:
  对于每个测试用例,您应该输出最小的总降低分数,每个测试用例一行。
样例输入:

3 
3 
3 3 3 
10 5 1 
3 
1 3 1 
6 2 3 
7 
1 4 6 4 2 4 3 
3 2 1 7 6 5 4

样例输出:

0 
3 
5

AC代码(java):

package 再次做作业;
import java.util.*;
//hdu-1789

class Node implements Comparable<Node>{		//自定义类型
	public int d;
	public int c;	
	public Node(int d) {
		this.d=d;
	}	
	@Override
	public int compareTo(Node node) {
		// TODO 自动生成的方法存根
		if(this.c!=node.c) {
			return node.c-this.c;	//降序:别人的减去自家的
		}
		else {
			return this.d-node.d;
		}
	}

}

public class Main {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int t=sc.nextInt();
		int ans=0;	//记录所扣分数
		
		while(t-->0) {
			int n=sc.nextInt();
			List<Node> list=new ArrayList<Node>();
			for(int i=0;i<n;i++) {
				list.add(new Node(sc.nextInt()));		
			}
			for(int i=0;i<n;i++) {
				list.get(i).c=sc.nextInt();
			}	

			Collections.sort(list);
			
			int i,j;
			int[] flag=new int[1005];	//标记此天数是否被占用过,因为最大值为1000,所以范围设置为1005
			for(i=0;i<n;i++) {
				for(j=list.get(i).d;j>=1;j--) {		//j的范围设置大于1,是因为天数是大于等于1的
					if(flag[j]==0) {
						flag[j]=1;
						break;
					}
				}
				if(j<1) {
					ans+=list.get(i).c;
				}
			}
			System.out.println(ans);
			ans=0;
		}
		
	}
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值