码迷,mamicode.com
首页 > 其他好文 > 详细

HDU - 4293 Groups (DP)

时间:2015-08-01 01:05:08      阅读:98      评论:0      收藏:0      [点我收藏+]

标签:

题目大意:有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;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

HDU - 4293 Groups (DP)

标签:

原文地址:http://blog.csdn.net/l123012013048/article/details/47178809

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!