zoukankan      html  css  js  c++  java
  • POJ 1678 I Love this Game!

    POJ_1678

        如果我们把差在[a,b]的范围内的两个数之间连一条边的话,就会发现实际上取数的过程就是在有向无环图上行走的过程,对于一个点来讲,如果选择了它,并把选择它的人看作先手的话,那么之后的选择形成的先手与后手的分差唯一的,于是我们就可以把选择每个节点看作一个状态并进行记忆化搜索。

        于是可以用f[i]表示如果当前选第i个数,并把选择这个数的人看作先手,从这个选择开始后续形成的分差的最大值。同时,在dp的过程中我们要认为后手选择的是最优的情况,所以有f[i]=a[i]-max{f[j]},其中a[i]表示第i个数的值,j为i的后继。

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #define INF 0x3f3f3f3f
    #define MAXD 10010
    int N, A, B, a[MAXD], f[MAXD];
    int cmp(const void *_p, const void *_q)
    {
    int *p = (int *)_p, *q = (int *)_q;
    return *p - *q;
    }
    void init()
    {
    int i, j, k;
    scanf("%d%d%d", &N, &A, &B);
    for(i = 0; i < N; i ++)
    scanf("%d", &a[i]);
    qsort(a, N, sizeof(a[0]), cmp);
    }
    int dfs(int cur)
    {
    if(f[cur] != -1)
    return f[cur];
    int i, j, k, ans = -INF;
    for(i = cur + 1; i < N && a[i] - a[cur] <= B; i ++)
    if(a[i] - a[cur] >= A && (k = dfs(i)) > ans)
    ans = k;
    if(ans == -INF)
    ans = 0;
    return f[cur] = a[cur] - ans;
    }
    void solve()
    {
    int i, j, k, ans = -INF;
    memset(f, -1, sizeof(f[0]) * N);
    for(i = 0; i < N; i ++)
    if(a[i] >= A && a[i] <= B && (k = dfs(i)) > ans)
    ans = k;
    printf("%d\n", ans == -INF ? 0 : ans);
    }
    int main()
    {
    int t;
    scanf("%d", &t);
    while(t --)
    {
    init();
    solve();
    }
    return 0;
    }


  • 相关阅读:
    HDU 4285
    Codeforces 242C
    Codeforces 811C
    Codeforces 883H
    Codeforces 371D
    Codeforces 926E
    牛客算法周周练17 解题报告
    牛客算法周周练17D
    牛客算法周周练17C
    牛客算法周周练17A
  • 原文地址:https://www.cnblogs.com/staginner/p/2389089.html
Copyright © 2011-2022 走看看