【题目描述】
老师在开学第一天就把所有作业都布置了,每个作业如果在规定的时间内交上来的话才有学分。每个作业的截止日期和学分可能是不同的。例如如果一个作业学分为10,要求在6天内交,那么要想拿到这10学分,就必须在第6天结束前交。
每个作业的完成时间都是只有一天。例如,假设有7次作业的学分和完成时间如下:
作业号
|
1
|
2
|
3
|
4
|
5
|
6
|
7
|
期限
|
1
|
1
|
3
|
3
|
2
|
2
|
6
|
学分
|
6
|
7
|
2
|
1
|
4
|
5
|
1
|
最多可以获得15学分,其中一个完成作业的次序为2,6,3,1,7,5,4,注意可能d还有其他方法。
你的任务就是找到一个完成作业的顺序获得最大学分。
【输入】
第一行一个整数N,表示作业的数量。
接下来N行,每行包括两个整数,第一个整数表示作业的完成期限,第二个数表示该作业的学分。
【输出】
输出一个整数表示可以获得的最大学分。保证答案不超过longint范围。
【输入样例】
7 1 6 1 7 3 2 3 1 2 4 2 5 6 1
【输出样例】
15
这道题和ybt上的1426 智力大冲浪 比较相像,一开始我就是直接用1426的代码做的,上代码——
1 #include<bits/stdc++.h>
2 using namespace std;
3 int n;
4 int k,m,p,w,ans,l,s;
5 bool u[1000001];
6 struct node{
7 int a,b;
8 bool operator <(const node &y)const
9 {
10 return b>y.b;
11 }
12 }x[1000001];
13 int read()
14 {
15 int f=1;char ch;
16 while((ch=getchar())<'0'||ch>'9')
17 if(ch=='-')f=-1;
18 int res=ch-'0';
19 while((ch=getchar())>='0'&&ch<='9')
20 res=res*10+ch-'0';
21 return res*f;
22 }
23 void write(int x)
24 {
25 if(x<0)
26 {
27 putchar('-');
28 x=-x;
29 }
30 if(x>9)write(x/10);
31 putchar(x%10+'0');
32 }
33 int main()
34 {
35 n=read();
36 for(int i=1;i<=n;i++)
37 {
38 x[i].a=read(),x[i].b=read();
39 s+=x[i].b;
40 }
41 sort(x+1,x+1+n);
42 for(int i=1;i<=n;i++)
43 {
44 int flag=0;
45 for(int j=x[i].a;j>=1;j--)
46 if(!u[j])
47 {
48 u[j]=true;
49 flag=1;
50 break;
51 }
52 if(!flag)
53 {
54 for(int j=n;j>=1;j--)
55 if(!u[j])
56 {
57 u[j]=1;
58 break;
59 }
60 s-=x[i].b;
61 }
62 }
63 write(s);
64 return 0;
65 }
然鹅只有可伶的50分,有五个点都TLE了┭┮﹏┭┮
所以说这道题肯定就没有这么简单啦(虽然说本来就是很简单的水题
那么我们进一步优化吧,,,
1 #include<iostream>
2 #include<cstdio>
3 #include<algorithm>
4 using namespace std;
5 struct homework
6 {
7 int k,date;
8 }a[1000001];
9 int read()
10 {
11 char ch=getchar();
12 int a=0,x=1;
13 while(ch<'0'||ch>'9')
14 {
15 if(ch=='-') x=-x;
16 ch=getchar();
17 }
18 while(ch>='0'&&ch<='9')
19 {
20 a=(a<<3)+(a<<1)+(ch-'0');
21 ch=getchar();
22 }
23 return a*x;
24 }
25 int cmp(homework x,homework y) //按照学分从大到小排序
26 {
27 return x.k>y.k;
28 }
29 int n,sum,q,hash[1000001];
30 int pan(int x)
31 {
32 for(int i=a[x].date;i>=1;i--)
33 {
34 if(hash[i]==0)
35 {
36 hash[i]=1;
37 return 1;
38 }
39 }
40 q=a[x].date; //如果到了这里,说明1~a[x].date已经安排满了,用q记录下来
41 return 0;
42 }
43 int main()
44 {
45 n=read();
46 for(int i=1;i<=n;i++)
47 {
48 a[i].date=read();
49 a[i].k=read();
50 }
51 sort(a+1,a+1+n,cmp);
52 for(int i=1;i<=n;i++)
53 {
54 if(a[i].date<q) continue; //直接跳出,节省时间
55 if(pan(i)) sum+=a[i].k;
56 }
57 printf("%d\n",sum);
58 return 0;
59 }