HDU - 4293 Groups (DP)

来源:互联网 发布:叫车软件 编辑:程序博客网 时间:2024/05/16 12:38

题目大意:有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 510struct 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;}
0 0
原创粉丝点击