家庭作业(信息学奥赛一本通 1430)

99封情书 提交于 2019-11-26 23:43:11

【题目描述】

老师在开学第一天就把所有作业都布置了,每个作业如果在规定的时间内交上来的话才有学分。每个作业的截止日期和学分可能是不同的。例如如果一个作业学分为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 }

//代码来自:https://www.cnblogs.com/xcg123/p/10994763.html

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!