题目大意:
  有一个长度为n的数列,A和B两个人轮流从两端取数,B先取,A想使分数严格小于B且尽量接近B,问两人分数之差最小是多少。

思路:
  折半搜索,先预处理出长度为part的最大差最小差,再预处理出后面一段能取到的不同差值,然后dfs,当范围等于part时,就在数组中二分查找一下。

 #include<cstdio>
#include<cctype>
#include<vector>
#include<ext/hash_set>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int inf=0x7fffffff,_inf=-0x80000000;
const int N=;
int a[N];
int max[N][N],min[N][N],ans,n,part;
inline void init() {
ans=_inf;
for(register int i=;i<=n;i++) {
for(register int j=;j<=n;j++) {
max[i][j]=_inf;
min[i][j]=inf;
}
}
for(register int i=;i<=n;i++) {
max[i][i-]=min[i][i-]=;
}
for(register int i=n;i;i--) {
for(register int j=i;j<=n;j++) {
int l=i,r=j;
int tmp=(a[l]>=a[r])?a[l++]:a[r--];
max[i][j]=std::max(a[l]+max[l+][r],a[r]+max[l][r-])-tmp;
min[i][j]=std::min(a[l]+min[l+][r],a[r]+min[l][r-])-tmp;
}
}
}
std::vector<int> v[N];
__gnu_cxx::hash_set<int> s;
void initPart2() {
part=std::min(,n/);
for(int i=;i<=n+-part*;i++) {
s.clear();
v[i].clear();
for(int j=;j<<<part;j++) {
int tmp=,l=i,r=i+part*-;
for(int k=;k<part;k++) {
tmp-=(a[l]>=a[r])?a[l++]:a[r--];
tmp+=(!(j&(<<k)))?a[l++]:a[r--];
}
if(s.find(tmp)==s.end()) {
s.insert(tmp);
v[i].push_back(tmp);
}
}
std::sort(v[i].begin(),v[i].end());
}
}
void dfs(int l,int r,int dif) {
if(r-l+==part*) {
std::vector<int>::iterator it=std::lower_bound(v[l].begin(),v[l].end(),-dif);
if(it==v[l].begin()&&*it==-dif) return;
if(it==v[l].end()||*it==-dif) it--;
if(dif+*it<) ans=std::max(ans,dif+*it);
return;
}
if(dif+min[l][r]>=) return;
if(dif+max[l][r]<=ans) return;
if(dif+max[l][r]<) {
ans=std::max(ans,dif+max[l][r]);
return;
}
int tmp=(a[l]>=a[r])?a[l++]:a[r--];
dfs(l+,r,dif+a[l]-tmp);
dfs(l,r-,dif+a[r]-tmp);
}
int main() {
getint();
while(~scanf("%d",&n)) {
for(register int i=;i<=n;i++) {
a[i]=getint();
}
init();
initPart2();
dfs(,n,);
if(ans!=_inf) {
printf("%d\n",-ans);
} else {
puts("The child will be unhappy...");
}
}
return ;
}

这段代码在SimpleOJ上交比暴力还慢。

[HDU6196]happy happy happy的更多相关文章

  1. hdu6196 happpy happy happy (meet in middle + 剪枝)

    题意 从1到n共计n(<=90)个物品,每个物品有一个价值a[i],儿子和爸爸轮流做游戏,儿子先手.儿子每次选价值最大的{最左边,最右边}的物品,如果价值一样大, 则选取最左边的物品. 爸爸每次 ...

随机推荐

  1. 大规模实时流处理平台架构-zz

    随着不同网络质量下接入终端设备种类的增多,服务端转码已经成为视频点播和直播产品中必备的能力之一.直播产品讲究时效性,希望在一定的时间内让所有终端看到不同尺寸甚至是不同质量的视频,因此对转码的实时性要求 ...

  2. aarch64_p1

    PEGTL-devel-1.3.1-2.fc26.aarch64.rpm 2017-02-14 08:00 63K fedora Mirroring Project PackageKit-1.1.6- ...

  3. LINUX修改、增加IP的方法,一张网卡绑定多个IP/漂移IP【转】

    临时增加IP命令:ifconfig eth0:1 ip地址 netmask 子网码 broadcast 广播地址 gateway 网关  ifconfig eth0:1 10.1.104.65 net ...

  4. TCP/IP详解(整理)

    1.概述 路由器是在网络层进行联通,而网桥是在链路层联通不同的网络. IP层用ICMP来与其他主机或路由器交换错误报文和其他的重要信息.应用程序也可以访问ICMP,两个诊断工具:Ping和Tracer ...

  5. 洛谷P1938 找工就业

    传送门啦 这个题本质就是跑一边最长路,重点就是在怎么建图上. 我们可以把点权放到边权上面,即将每一个边的终点点权当做这个边的边权,这个题里就是将工钱 $ d $ 当做边权. 如果这一条边需要坐飞机才能 ...

  6. Trie树子节点快速获取法

    今天做了一道leetcode上关于字典树的题:https://leetcode.com/problems/word-search-ii/#/description 一开始坚持不看别人的思路,完全自己写 ...

  7. ROS + Caffe 机器人操作系统框架和深度学习框架笔记 (機器人控制與人工智能)

    ROS + Caffe,这里以环境中物体识别为示例,机器人怎么知道环境里面有什么呢? [0.0567392 - n03376595 folding chair][0.0566773 - n040999 ...

  8. sqlserver游标概念与实例全面解说

    引言 我们先不讲游标的什么概念,步骤及语法,先来看一个例子:   ?????? 表一 OriginSalary????????????????????????????????????????????? ...

  9. LeetCode664. Strange Printer

    There is a strange printer with the following two special requirements: The printer can only print a ...

  10. Effective STL 43: Prefer algorithm calls to hand-written loops

    Effective STL 43: Prefer algorithm calls to hand-written loops */--> div.org-src-container { font ...