题目大意
FJ
要录制节目,每个节目具有一个指定的开始时间和结束时间。FJ
具有两台摄像机,可以同时录制两个节目(FJ
一旦选择了某个节目来录制,就一定要录制完该节目)。请帮他确定录制的方案,使得 FJ
可以录制最多的节目,以提供给那些奶牛的粉丝们。
解题思路
贪心思路
贪心策略:
-
按照结束时间排序。
-
若节目可以放,则必定放。
-
如果有一个节目两组都可以放,则放在结束时间长的那一组,因为可以使得另一组可能放得下时间更长的节目。
DP思路
首先我们将所有节目按照起始时间从小到大排序。这样是为了二分查找。
设 \(dp(i,j)\) 意为第一台摄像机正在考虑要不要拍摄第 \(i\) 个节目,第二台摄像机正在考虑要不要拍第 \(j\) 个节目。
每个 \(dp\) 都要考虑四种情况,分别是:拍 \(i\),不拍 \(i\),拍 \(j\),不拍 \(j\) 。
AC CODE
贪心
#include<bits/stdc++.h>
#define int long long
using namespace std;
long long n, ans;
struct abc
{
long long st, en, id;
bool operator < (const abc &tmp) const
{
if(en != tmp.en)
return en < tmp.en;
return st < tmp.st;
}
}a[250];
signed main()
{
scanf("%lld", &n);
for(int i = 1; i <= n; ++i)
scanf("%lld%lld", &a[i].st, &a[i].en);
sort(a + 1, a + n + 1);
int c1 = 0, c2 = 0;
for(int i = 1; i <= n; ++i)
{
if(a[i].st >= c1)
{
c1 = a[i].en;
ans++;
}
else if(a[i].st >= c2)
{
c2 = a[i].en;
ans++;
}
if(c1 < c2) swap(c1, c2);
}
printf("%lld\n", ans);
return 0;
}
DP
#include <bits/stdc++.h>
using namespace std;
struct Fastio
{
Fastio operator>>(int &x)
{
x = 0;
int f = 0;
char c = getchar();
while (c < '0' || c > '9')
f |= c == '-', c = getchar();
while (c >= '0' && c <= '9')
x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
x = f ? -x : x;
return *this;
}
Fastio &operator<<(const char c)
{
putchar(c);
return *this;
}
Fastio &operator<<(const char *str)
{
int cur = 0;
while (str[cur])
putchar(str[cur++]);
return *this;
}
Fastio &operator<<(int x)
{
if (x == 0)
{
putchar('0');
return *this;
}
if (x < 0) putchar('-'),x = -x;
static int sta[45], top = 0;
while (x)
sta[++top] = x % 10, x /= 10;
while (top)
putchar(sta[top] + '0'), --top;
return *this;
}
}io;
int n;
int a[250];
int b[250];
int d[250][250];
struct Node
{
int st, en;
} node[250];
bool cmp(Node a, Node b)
{
return a.st < b.st;
}
int dp(int i, int j)
{
if (i > j)
swap(i, j);
if (d[i][j])
return d[i][j];
int temp1, temp2, ans = 0;
temp1 = lower_bound(&a[i] + 1, &a[n] + 1, b[i]) - a;
temp1 = max(temp1, j + 1);
temp2 = lower_bound(&a[j] + 1, &a[n] + 1, b[j]) - a;
if (temp1 != n + 1)
{
ans = max(ans, dp(temp1, j) + 1);
}
if (temp2 != n + 1)
{
ans = max(ans, dp(i, temp2) + 1);
}
if (j != n)
{
ans = max(ans, dp(i, j + 1));
ans = max(ans, dp(j + 1, j));
}
return d[i][j] = ans;
}
signed main()
{
io >> n;
for (int i = 1; i <= n; i++)
io >> node[i].st >> node[i].en;
sort(node + 1, node + n + 1, cmp);
for (int i = 1; i <= n; i++)
{
a[i] = node[i].st;
b[i] = node[i].en;
}
if (n == 1)
io << 1 << "\n";
else
io << dp(1, 2) + 2 << "\n";
}