题目大意:有N个人,人人之间可以组成一个团队,现在N个人各说一句话,说自己前面有多少人,后面有多少人
现在要求你判断这N个人中最多有多少人说真话
解题思路:参考了别人的
设有n个人,其中有一个人说了他前面有a个人,后面有b个人,那么他所在的区间就变成了[a + 1, n - b],那么就可以将这个人归到[a + 1, n - b]
如果[a + 1, n - b]的区间的人数超过了 n - a -b,那么就可以将其他的人忽略掉,因为这个区间最多有n-a-b个人
那么现在的问题就变成了,如何选择不相交的区间,使的区间内的人数的和最大
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 510
struct Node {
int l, r;
Node() {}
Node(int l, int r ): l(l), r(r) {}
bool operator < (const Node &b) const {
if (r == b.r)
return l < b.l;
return r < b.r;
}
}node[N];
int num[N][N], dp[N];
int n, cnt;
void init() {
memset(num, 0, sizeof(num));
int x, y;
cnt = 0;
for (int i = 0; i < n; i++) {
scanf("%d%d", &x, &y);
if (x + y >= n || num[x + 1][n - y] == n - x - y)
continue;
if (!num[x + 1][n - y])
node[cnt++] = Node(x + 1, n - y);
++num[x + 1][n - y];
}
}
void solve() {
sort(node, node + cnt);
memset(dp, 0, sizeof(dp));
int ans = 0;
for (int i = 0; i < cnt; i++) {
int Max = 0;
for (int j = 0; j < i; j++)
if (node[j].r < node[i].l)
Max = max(Max, dp[j]);
dp[i] = Max + num[node[i].l][node[i].r];
ans = max(ans, dp[i]);
}
printf("%d\n", ans);
}
int main() {
while (scanf("%d", &n) != EOF) {
init();
solve();
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-18 04:34:57