題意:有n個節目,每個節目有一個持續的天數,你一天只能看一個節目,問你這麼多天最多能看幾個節目
題解:貪心,我們把那種截止日期最近的節目,都看了。把節目按照截止日期從小到大排序。接下來一個一個節目看,可以用數組標記的方法,for循環判斷在當前節目的區間內,還有有沒有天數是空閒的。
最後一步的for循環,可以用線段樹代替,這樣的話就是O(log(k))的效率查找當前節目是否可以觀看。 k爲區間的長度。
兩種方法都可以過
for循環
struct Node
{
int l;
int r;
}b[100005];
int cmp(Node a,Node b)
{
if(a.r==b.r)
return a.l>b.l;
return a.r<b.r;
}
class Solution {
public:
int vis[100005];
int maxEvents(vector<vector<int>>& events) {
int len = 0;
int p = 0;
for(int i=0;i<events.size();i++)
{
len=max(len,events[i][1]);
b[p].l = events[i][0];
b[p].r = events[i][1];
p++;
}
sort(b,b+p,cmp);
int ans=0;
for(int i=0;i<p;i++)
{
for(int j=b[i].l;j<=b[i].r;j++)
{
if(!vis[j])
{
vis[j]=1;
ans++;
break;
}
}
}
return ans;
}
};
線段樹
struct Node
{
int l;
int r;
}b[100005];
int cmp(Node a,Node b)
{
if(a.r==b.r)
return a.l>b.l;
return a.r<b.r;
}
class Solution {
public:
int num[100005*4];
int maxEvents(vector<vector<int>>& events) {
int len = 0;
int p = 0;
for(int i=0;i<events.size();i++)
{
len=max(len,events[i][1]);
b[p].l = events[i][0];
b[p].r = events[i][1];
p++;
}
sort(b,b+p,cmp);
int ans=0;
for(int i=0;i<p;i++)
{
int pos = query(1,1,len,b[i].l,b[i].r,0);
if(pos!=-1)
{
ans++;
update(1,1,len,pos,1);
}
}
return ans;
}
void pushup(int node)
{
if(num[node<<1]==num[node<<1|1])
num[node]=num[node<<1];
else
num[node]=-1;
}
void update(int node,int l,int r,int i,int val)
{
if(l==r&&l==i)
{
num[node]=val;
return;
}
int mid = (l+r)/2;
if(i<=mid)
update(node<<1,l,mid,i,val);
if(i>mid)
update(node<<1|1,mid+1,r,i,val);
pushup(node);
}
int query(int node,int l,int r,int start,int end,int val)
{
if(start<=l&&r<=end)
{
if(num[node]!=-1)
{
if(num[node]==val)
return l;
else
return -1;
}
}
int mid = (l+r)/2;
int res;
if(start<=mid)
{
res = query(node<<1,l,mid,start,end,val);
if(res!=-1)
return res;
}
if(end>mid)
{
res = query(node<<1|1,mid+1,r,start,end,val);
}
return res;
}
};