博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 1678 I Love this Game!
阅读量:5162 次
发布时间:2019-06-13

本文共 1351 字,大约阅读时间需要 4 分钟。

POJ_1678

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

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

#include
#include
#include
#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; }

转载于:https://www.cnblogs.com/staginner/archive/2012/03/10/2389089.html

你可能感兴趣的文章
团队工作第二天
查看>>
System类
查看>>
tableView
查看>>
Happy Great BG-卡精度
查看>>
Xamarin Visual Studio不识别JDK路径
查看>>
菜鸟“抄程序”之道
查看>>
Ubuntu下关闭防火墙
查看>>
TCP/IP 邮件的原理
查看>>
原型设计工具
查看>>
windows下的C++ socket服务器(4)
查看>>
css3 2d转换3d转换以及动画的知识点汇总
查看>>
【Java】使用Eclipse进行远程调试,Linux下开启远程调试
查看>>
对Vue为什么不支持IE8的解释之一
查看>>
计算机改名导致数据库链接的诡异问题
查看>>
Java8内存模型—永久代(PermGen)和元空间(Metaspace)(转)
查看>>
ObjectiveC基础教程(第2版)
查看>>
centos 引导盘
查看>>
Notes of Daily Scrum Meeting(12.8)
查看>>
Apriori算法
查看>>
onlevelwasloaded的调用时机
查看>>