题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6196

题意:给你长度为n的序列,爸爸和儿子玩一个游戏,儿子先手,儿子每次都选择最左边与最右边最大的那个拿走(若左右相等拿左边),爸爸可以任意拿最左边或者最右边。

解法:膜一发题解:http://blog.csdn.net/snowy_smile/article/details/77929954

首先,我们DP两个东西——
1, mx[l][r]表示对于区间[l, r],儿子先手,爸爸所能拿到的最大价值差值(差值是爸爸减儿子)
2, mn[l][r]表示对于区间[l, r],儿子先手,爸爸所能拿到的最小价值差值(差值是爸爸减儿子) 那么——
我们尝试使用搜索解决这个问题 dfs(l, r, dif)表示当前还没有取的区间范围是[l, r],儿子先手,此时爸爸减儿子的差值为dif。 那么——
1,这时先考虑剪枝—— 设置初始ANS = -inf; void dfs(int l, int r, int dif)
{
if (dif + mn[l][r] >= 0) return; //哪怕取一个最小值,都会赢了儿子,是个无效状态
if (dif + mx[l][r] <= ANS) return; //哪怕取一个最大值,差值都依然太小了,最优性剪枝
if (dif + mx[l][r] < 0) //取一个最大值,使得差值尽可能小,最优性剪枝
{
gmax(ANS, dif + mx[l][r]);
}
} 2,再模拟儿子的操作,获得新的(l, r, dif) 3,接着需要进一步地考虑爸爸的操作——
<1>取l,变成dfs(l + 1, r, dif + a[l]);
<2>取r,变成dfs(l, r - 1, dif + a[r]); 4,考虑如何获得DP数组mn[][]和mx[][]—— mn[i][i - 1] = mx[i][i - 1] = 0; for(int l = n; l >= 1; --l)
{
for(int r = l; r <= n; ++r)
{
先模拟儿子的操作,获得新的(ll, rr)
然后考虑父亲的操作——
1,取ll:
gmax(mx[l][r], a[ll] + mx[ll + 1][rr]);
gmin(mn[l][r], a[ll] + mn[ll + 1][rr]);
2,取rr:
gmax(mx[l][r], a[rr] + mx[ll][rr - 1]);
gmin(mn[l][r], a[rr] + mn[ll][rr - 1]); }
}

题解摘自上面的博客,我直接搜索T了。然后加入桑心病况的卡时间的剪枝,可以跑到0ms。。。orz
#include <bits/stdc++.h>
using namespace std;
const int maxn = 110;
const int inf = 0x3f3f3f3f;
//mx[l][r]表示对于区间[l,r],儿子先手,爸爸能拿到的最大价值差值(差值是爸爸减去儿子)
//mn[l][r]表示对于区间[l,r],儿子先手,爸爸能拿到的最小价值差值(差值是爸爸减去儿子)
int LIM = 0.5*CLOCKS_PER_SEC;
int ST;
int n, a[maxn], mn[maxn][maxn], mx[maxn][maxn];
void pre_deal(){
memset(mn, 0x7f, sizeof(mn));
memset(mx, 0x80, sizeof(mx));
for(int i=1; i<=n+1; i++) mn[i][i-1]=mx[i][i-1]=0;
for(int l=n; l>=1; l--){
for(int r=l; r<=n; r++){
int newl=l, newr = r, sub;
if(a[newl]>=a[newr]) sub=a[newl++];
else sub=a[newr--];
mx[l][r] = max(mx[l][r], a[newl]+mx[newl+1][newr]-sub);
mx[l][r] = max(mx[l][r], a[newr]+mx[newl][newr-1]-sub);
mn[l][r] = min(mn[l][r], a[newl]+mn[newl+1][newr]-sub);
mn[l][r] = min(mn[l][r], a[newr]+mn[newl][newr-1]-sub);
}
}
}
int ans;
void dfs(int l, int r, int dif)
{
if(l>r){
ans = max(ans, dif);
return;
}
if(dif+mn[l][r]>=0) return;
if(dif+mx[l][r]<=ans) return;
if(dif+mx[l][r]<0){
ans = max(ans, dif+mx[l][r]);
return;
}
if(clock()-ST>LIM) return;
int sub;
if(a[l]>=a[r]) sub=a[l++];
else sub=a[r--];
dfs(l+1, r, dif+a[l]-sub);
dfs(l, r-1, dif+a[r]-sub);
}
int main()
{
while(~scanf("%d", &n))
{
for(int i=1; i<=n; i++) scanf("%d", &a[i]);
pre_deal();
ST = clock();
ans = -inf;
dfs(1, n, 0);
if(ans == -inf){
puts("The child will be unhappy...");
}else{
printf("%d\n", -ans);
}
}
return 0;
}
												

HDU 6196 happy happy happy 爆搜加剪枝的更多相关文章

  1. HDOJ/HDU Tempter of the Bone(深搜+奇偶性剪枝)

    Problem Description The doggie found a bone in an ancient maze, which fascinated him a lot. However, ...

  2. 【深搜加剪枝】【HDU1455】【Sticks】

    题目大意:有一堆木棍 由几个相同长的木棍截出来的,求那几个相同长的木棍最短能有多短? 深搜+剪枝 具体看代码 #include <cstdio> #include <cstdlib& ...

  3. ROADS POJ - 1724 约束最短路 暴搜 加剪枝

    http://poj.org/problem?id=1724 题意:最短路的模板,不过每条边加上一个费用,要求总费用不超过k 题解:不能用dijkstra ,直接暴力,dfs维护len和cost. 普 ...

  4. 2015 UESTC 搜索专题E题 吴队长征婚 爆搜

    吴队长征婚 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/61 Descri ...

  5. HDU 4403 A very hard Aoshu problem(dfs爆搜)

    http://acm.hdu.edu.cn/showproblem.php?pid=4403 题意: 给出一串数字,在里面添加一个等号和多个+号,使得等式成立,问有多少种不同的式子. 思路: 数据量比 ...

  6. hdu 5031 Lines 爆搜

    事实上嘞,这个线能够仅仅延伸一端 然后嘞,爆搜一次就能够 最后嘞,600-800ms过 本弱就是弱啊.你来打我呀-- #include<iostream> #include<cstr ...

  7. HDU 5961:传递(暴搜)

    http://acm.hdu.edu.cn/showproblem.php?pid=5961 题意:中文题意.给出两个图,判断这个两个图是否都是传递的.注意一下传递的定义要看清,一开始没看清连样例都看 ...

  8. hdu5323 Solve this interesting problem(爆搜)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Solve this interesting problem Time Limit ...

  9. bzoj1306: [CQOI2009]match循环赛(模拟爆搜)

    Input第一行包含一个正整数n,队伍的个数.第二行包含n个非负整数,即每支队伍的得分.Output输出仅一行,即可能的分数表数目.保证至少存在一个可能的分数表.Sample Input 6 5 6 ...

随机推荐

  1. Jackson 使用

    // 序列化出来的 JSON, 不包含值为 NULL 类型字段. mapper.setSerializationInclusion(Include.NON_NULL); Jackson provide ...

  2. [AT2384] [agc015_f] Kenus the Ancient Greek

    题目链接 AtCoder:https://agc015.contest.atcoder.jp/tasks/agc015_f 洛谷:https://www.luogu.org/problemnew/sh ...

  3. 【BZOJ4059】Non-boring sequences

    Solution 记序列为\(a\),计算出与\(a_i\)相等的前一个元素的位置\(pre_i\),以及后一个元素的位置\(nex_i\),显然,对于那些左端点处于\((pre_i,i]\)以及右端 ...

  4. 洛谷 P1199 三国游戏 解题报告

    P1199 三国游戏 题目描述 小涵很喜欢电脑游戏,这些天他正在玩一个叫做<三国>的游戏. 在游戏中,小涵和计算机各执一方,组建各自的军队进行对战.游戏中共有\(N\)位武将(\(N\)为 ...

  5. Linux内核分析实验四----

    一.用户态.内核态 权限分级——为了系统本身更稳定,使系统不宜崩溃.(并不是所有程序员缩写的代码都很健壮!!) x86 CPU四种不同的执行级别:0(内核态)—3(用户态) 区分方法:CS:EIP(C ...

  6. Android ProgressBar的使用

    Android 基础教程之-------Android ProgressBar的使用http://blog.csdn.net/Android_Tutor/article/details/5695170 ...

  7. C标准库函数--文件IO操作函数。

    C标准库文件读写函数总结:都是对文件流进行输入输出的函数分为对文件的有格式读写以及无格式读写 一.文件的无格式读写根据每次读写字符的数量,分为三类:1.按字符读写文件 按字符读有三个函数:以下三个函数 ...

  8. C++命名规则 (转载仅作参考)

    如果想要有效的管理一个稍微复杂一点的体系,针对其中事物的一套统一.带层次结构.清晰明了的命名准则就是必不可少而且非常好用的工具. 活跃在生物学.化学.军队.监狱.黑社会.恐怖组织等各个领域内的大量有识 ...

  9. 【题解】【雅礼集训 2017 Day5】远行 LOJ 6038 LCT

    Prelude 快要THUWC了,练一练板子. 传送到LOJ:o(TヘTo) Solution 首先有一条定理. 到树中任意一点的最远点一定是直径的两个端点之一. 我也不会证反正大家都在用,似乎可以用 ...

  10. Linux运维三:系统目录结构

    Linux系统目录结构官方参考:http://www.pathname.com/fhs/ 1:Linux树状目录结构图 下面目录中标红的是必须要掌握的! 2:根目录  目录 描述 / 第一层次结构的根 ...