HDU-1789- Doing Homework again

Doing Homework again

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 16026    Accepted Submission(s): 9340


Problem Description
Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot of homework to do. Every teacher gives him a deadline of handing in the homework. If Ignatius hands in the homework after the deadline, the teacher will reduce his score of the final test. And now we assume that doing everyone homework always takes one day. So Ignatius wants you to help him to arrange the order of doing homework to minimize the reduced score.
 

Input
The input contains several test cases. The first line of the input is a single integer T that is the number of test cases. T test cases follow.
Each test case start with a positive integer N(1<=N<=1000) which indicate the number of homework.. Then 2 lines follow. The first line contains N integers that indicate the deadlines of the subjects, and the next line contains N integers that indicate the reduced scores.
 

Output
For each test case, you should output the smallest total reduced score, one line per test case.
 

Sample Input
 
 
333 3 310 5 131 3 16 2 371 4 6 4 2 4 33 2 1 7 6 5 4
 
Sample Output
 
 
035

由于我的水平太菜,这道题想了一天都没想出来怎么做,最后还是看我师父的博客才弄明白咋回事?看来还是要多刷点题涨涨见识~这道题我之前想过了两种写法结果都没过。第一种:按扣分的分值降序排序,再由一个数组记录下标来表示写作业需要的天数就像这样:

for(int i=0;i<n;i++){
	scanf("%d%d",&a[i].deadline,&a[i].score);
	b[i]=i+1;//用数组来记录写完一个作业是在第几天完成的 
}
sort(a,a+n,cmp);
int ans=0;
for(int i=0;i<n;i++){
	if(a[i].deadline<b[i]) ans=ans+a[i].score;/*当时找规律觉得如果
		截止时间比当时的天数要小就无法完成.既然知道了这一天的作业在这一天
		无法完成那这一天的这份作业就放弃换成下一天的作业,同时之后的b[i]
		多要减一(因为后续的任务都要提前一天*/
		for(int j=i;j<n;j++){
			b[j]=b[j]-1;
		} 
} 
向上一种写法就没过,然后又脑洞大开想出了第二种诡异的写法(就不发出来了,丢人)结果还是没过

    这是正确写法:

#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
using namespace std;
int b[100005];
struct homework{
	int deadline;
	int score;
}a[10005];
int cmp1(homework a,homework b){
	if(a.score!=b.score) return a.score>b.score;
	else return a.deadline<b.deadline;
}
int main(){
	int t,i,j,n;
	scanf("%d",&t);
	while(t--){
		int ans=0;
		scanf("%d",&n);
		for(i=0;i<n;i++) scanf("%d",&a[i].deadline);
		for(i=0;i<n;i++) scanf("%d",&a[i].score);
		/*俩段输入一定要分开不要像我之前这样写
		 for(int i=0;i<n;i++) scanf("%d%d",&a[i].deadline,&a[i].score)*/
		memset(b,0,sizeof(b));
		sort(a,a+n,cmp1);
		for(i=0;i<n;i++){
			for(j=a[i].deadline;j>0;j--){/*用一个数组b[j]来记录这一天有没有被占用
			如果被占用去判断下一天,最后如果j==0说明这一天全被占用这一天的作业也就
			无法完成*/ 
				if(!b[j]){
					b[j]=1;
					break;
				}
			}
			if(j==0) ans=ans+a[i].score;
		}
		printf("%d\n",ans);
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值