P2255 [USACO14JAN]Recording the Moolympics S

更好的阅读体验

传送门

题目大意

FJ 要录制节目,每个节目具有一个指定的开始时间和结束时间。FJ具有两台摄像机,可以同时录制两个节目(FJ 一旦选择了某个节目来录制,就一定要录制完该节目)。请帮他确定录制的方案,使得 FJ 可以录制最多的节目,以提供给那些奶牛的粉丝们。

解题思路

贪心思路

贪心策略:

  • 按照结束时间排序。

  • 若节目可以放,则必定放。

  • 如果有一个节目两组都可以放,则放在结束时间长的那一组,因为可以使得另一组可能放得下时间更长的节目。

DP思路

首先我们将所有节目按照起始时间从小到大排序。这样是为了二分查找。

d p ( i , j ) dp(i,j) dp(i,j) 意为第一台摄像机正在考虑要不要拍摄第 i i i 个节目,第二台摄像机正在考虑要不要拍第 j j j 个节目。

每个 d p dp dp 都要考虑四种情况,分别是:拍 i i i,不拍 i i i,拍 j j j,不拍 j 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";
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值