HDU 4293 Groups

来源:互联网 发布:同济大学网络教育招生 编辑:程序博客网 时间:2024/05/21 21:01

  每个有效的(A,B),都能对应到一个group的区间[A+1,N-B]。把每个group看作一个节点,权值为这个group的player出现的次数(且不能超过区间长度)。若两个区间不冲突,从左边的区间向右边的连一条有向边。加上源点和终点(连上所有节点),求最长路。

//2012-09-16 18:56:27Accepted4293156MS2260K1900 BG++Aros#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;const int MAXN = 500+5, MAXM = 300000+5;const int INF = 0x3f3f3f3f;int N, a, b, A[MAXN], B[MAXN];int n, s, t, mp[MAXN][MAXN];int val[MAXN], d[MAXN];int e, head[MAXN], next[MAXM], v[MAXM];bool inq[MAXN];queue<int> Q;void addedge(int x, int y){    v[e] = y;    next[e] = head[x]; head[x] = e++;}void spfa(){    for (int i = 1; i <= n; i++)        d[i] = 0;    memset(inq, 0, sizeof(inq));    Q.push(s);    while (!Q.empty())    {        int u = Q.front(); Q.pop();        inq[u] = 0;        for (int i = head[u]; i != -1; i = next[i])            if (d[v[i]] < d[u]+val[v[i]])            {                d[v[i]] = d[u]+val[v[i]];                if (!inq[v[i]])                {                    Q.push(v[i]);                    inq[v[i]] = 1;                }            }    }}int main(){    while (scanf("%d", &N) != EOF)    {        e = 0; n = 0;        memset(head, -1, sizeof(head));        memset(mp, 0, sizeof(mp));        memset(val, 0, sizeof(val));        for (int i = 1; i <= N; i++)        {            scanf("%d%d", &a, &b);            if (a+b >= N)                continue;            int x = a+1, y = N-b, &m = mp[x][y];            if (!m)            {                m = ++n;                A[m] = x;                B[m] = y;            }            val[m] = min(B[m]-A[m]+1, val[m]+1);        }        for (int i = 1; i <= n; i++)            for (int j = 1; j <= n; j++)                if (B[i] < A[j])                    addedge(i, j);        s = n+1, t = n+2; val[s] = val[t] = 0;        for (int i = 1; i <= n; i++)            addedge(s, i), addedge(i, t);        n += 2;        spfa();        printf("%d\n", d[t]);    }    return 0;}


  更新dp解法,d[i]表示长度为i且包含以I结尾的区间时最大的人数。

//2012-09-20 16:05:55Accepted429346MS1224K1178 BG++Aros#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAXN = 500+5;const int INF = 0x3f3f3f3f;int N, a, b, A[MAXN], B[MAXN], r[MAXN];int mp[MAXN][MAXN], num[MAXN], d[MAXN];bool cmp(const int a, const int b){    return B[a] < B[b];}int main(){    while (scanf("%d", &N) != EOF)    {        memset(mp, 0, sizeof(mp));        memset(num, 0, sizeof(num));        memset(d, 0, sizeof(d));        int n = 0, ans = 0;        for (int i = 1; i <= N; i++)        {            scanf("%d%d", &a, &b);            if (a+b >= N)                continue;            int &m = mp[a+1][N-b];            if (!m)            {                m = ++n;                A[n] = a+1;                B[n] = N-b;                r[n] = n;            }            num[m] = min(num[m]+1, N-a-b);        }        sort(r+1, r+1+n, cmp);        for (int i = 1; i <= n; i++)            for (int j = 0; j < A[r[i]]; j++)                d[B[r[i]]] = max(d[B[r[i]]], d[j]+num[r[i]]);        for (int i = 1; i <= N; i++)            ans = max(ans, d[i]);        printf("%d\n", ans);    }    return 0;}


原创粉丝点击