FZU 2101

来源:互联网 发布:剑灵龙女完美身材数据 编辑:程序博客网 时间:2024/06/05 08:39
Problem 2101 大三的美好时光

Accept: 69    Submit: 387
Time Limit: 3000 mSec    Memory Limit : 32768 KB

 Problem Description

依稀记得自己踏入福大时学长学姐的甜美笑脸,可是一转眼的功夫自己就是大三的学长了。时间匆匆而过也就算了,bluesun痛苦的是,到大三了校选课还没有修满,再加上院选和必修课,bluesun的大三注定是异常辛苦的一年。

Bluesun总是喜欢把要做的事情在最短的时间里做完,所以他决定在必修课必选之外,选择一种使自己可以得到最多学分的方案(不管是院选的学分还是校选的,bluesun只要求学分尽量多)。

 Input

数据有多组,请处理到文件结尾。

每组数据的第一行为n(n表示有n门课程可供选择)接下来n行,每行4个整数,t 、l、 r和 v,如果t==0,则表示这门课程是必修课,否则为院选课或者是校选课,l和r表示该门课程占用的时间段为[l,r],v表示该门课程占几个学分。

输入数据均为整数,并且保证必修课的时间不会有交叉,1<=n<=100000,0<=v<=10000,1<=l<=r<=2^30。

 Output

每组测试输出一个整数,每个整数占1行,表示bluesun这个学期最多可以修多少个学分。

 Sample Input

11 1 1 2

 Sample Output

2

 Source

FOJ有奖月赛-2012年11月


POINT:

离散化后长度最多20W。用r从小到大排序。Dp的时候把和必修课冲突的课去除。

重点是怎么判断和必修课冲突,利用sum数组,必修课的时间全部sum[time]=1。然后利用前缀和,就知道一段区间里有没有1了。o(1)的效率查询。


#include <string>#include <string.h>#include <iostream>#include <queue>#include <math.h>#include <stdio.h>#include <algorithm>using namespace std;#define LL long longconst int maxn = 100000+55;int temp[maxn*2];int sum[maxn*2];int dp[maxn*2];struct node{int t,l,r,v;}a[maxn];bool cmd(node a,node b){return a.r<b.r;}int main(){int n;while(~scanf("%d",&n)){int cnt=0;for(int i=1;i<=n;i++){scanf("%d %d %d %d",&a[i].t,&a[i].l,&a[i].r,&a[i].v);temp[++cnt]=a[i].l;temp[++cnt]=a[i].r;sum[i]=sum[n+i]=0;}sort(temp+1,temp+1+cnt);int sz=unique(temp+1,temp+1+cnt)-temp-1;int val=0;for(int i=1;i<=n;i++){a[i].l=lower_bound(temp+1, temp+1+sz, a[i].l)-temp;a[i].r=lower_bound(temp+1, temp+1+sz, a[i].r)-temp;if(!a[i].t){for(int j=a[i].l;j<=a[i].r;j++) sum[j]=1;val+=a[i].v;}}for(int i=1;i<=sz;i++){sum[i]+=sum[i-1];dp[i]=0;}sort(a+1,a+1+n,cmd);for(int i=1,j=1;i<=sz;i++){dp[i]=dp[i-1];for(;j<=n&&a[j].r==i;j++){if(a[j].t&&sum[a[j].r]-sum[a[j].l-1]==0){dp[i]=max(dp[i],dp[a[j].l-1]+a[j].v);}}}printf("%d\n",val+dp[sz]);}return 0;}



原创粉丝点击