题意:两个人取数字,每次要取比对方取的数字大[a,b],问player1对player2的最大分差是多少。
思路:用dp[i]表示当前的人选第i个数作为第一个数字,可以获得的最大分差。这是一个先后手不断交换的过程,每次后手也会选择最优策略,因此dp[i]=c[i]-op,op表示后手作为之后的先手去取能造成的最大分差。
代码:
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<iostream>
#include<map>
#include<vector>
#include<set>
#include<queue>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxv = 1e4 + 4;
int t, n, a, b, dp[maxv], c[maxv];//dp[i]表示当前的人第一个选第i个数可以获得的最大分差
int dfs(int x)
{
if (dp[x] != -inf)
{
return dp[x];
}
int op = -inf;
for (int j = x + 1; j <= n; j++)
{
if (c[j] - c[x] >= a && c[j] - c[x] <= b)
{
op = max(op, dfs(j));
}
}
if (op == -inf)
{
dp[x] = c[x];
}
else
{
dp[x] = c[x] - op;
}
return dp[x];
}
int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d %d %d", &n, &a, &b);
for (int i = 1; i <= n; i++)
{
scanf("%d", &c[i]);
dp[i] = -inf;
}
sort(c + 1, c + 1 + n);
int ans = -inf;
for (int i = 1; i <= n; i++)
{
if (c[i] >= a && c[i] <= b)
ans = max(ans, dfs(i));
}
printf("%d\n", ans == -inf ? 0 : ans);
}
return 0;
}