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): 17622 Accepted Submission(s): 10252
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.
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
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
Sample Output
0
3
5
Author
lcy
Source
Recommend
题目连接:
分析:
非常经典的贪心题
在自己学校贪心专项的时候写过这道题,自己没有思考出来,还是看了题解,但总算搞懂了
今天在csu又遇到了这道题,开心
贪心思想:先将作业排序:扣分大的排前面,扣分相同的截至时间小的放前面
开一个标记数组,从排序号的第一个作业开始遍历,作业的完成时间安排在作业截至时间的前一天,如果前一天被占用了的话,就看前前天,如果前前天没有被占用的话,就安排在前前天,如果前前天也被占用了的话,就继续前移,如果没有时间给你安排此作业的话,那么此作业就必须被扣分了
注意:一个作业:day:3,权值:5,截止时间是4,就是第四天以前,所以一开始是安排在第三天
code:
#include<bits/stdc++.h> using namespace std; typedef long long LL; #define max_v 1005 int vis[max_v]; struct node { int d,w; }p[max_v]; bool cmp(node a,node b)//扣分大的排前面,扣分相同的截至时间小的放前面 { if(a.w!=b.w) { return a.w>b.w; } else { return a.d<b.d; } } int main() { int t; cin>>t; int n; while(t--) { memset(vis,0,sizeof(vis));//天数占用情况标记数组 cin>>n; for(int i=0;i<n;i++) { cin>>p[i].d; } for(int i=0;i<n;i++) { cin>>p[i].w; } sort(p,p+n,cmp); int sum=0; for(int i=0;i<n;i++) { if(vis[p[i].d]==0)//没有被占用 { vis[p[i].d]=1;//直接安排 }else//被占用了 { int f=0; for(int j=p[i].d-1;j>=1;j--)//在前面找一个没有被占用的天,如果没有那此作业就是要被扣分的 { if(vis[j]==0) { vis[j]=1; f=1; break; } } if(f==0) { sum+=p[i].w; } } } cout<<sum<<endl; } return 0; }
心之所向,素履以往