[HDU6196]happy happy happy
题目大意:
有一个长度为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的更多相关文章
- hdu6196 happpy happy happy (meet in middle + 剪枝)
题意 从1到n共计n(<=90)个物品,每个物品有一个价值a[i],儿子和爸爸轮流做游戏,儿子先手.儿子每次选价值最大的{最左边,最右边}的物品,如果价值一样大, 则选取最左边的物品. 爸爸每次 ...
随机推荐
- Chapter 4 深入理解Caffe MNIST DEMO中的LeNet网络模型
明代思想家王阳明提出了"知行合一",谓认识事物的道理与在现实中运用此道理,是密不可分的一回事.我以为这样的中国哲学话语,对于学习者来说,极具启发意义,要细细体会.中华文明源远流长, ...
- Maven仓库国内镜像站
感谢阿里巴巴,搭建并公开了Maven仓库的国内镜像站.话外:使用Maven的官方仓库真的是太slow了! 在<Maven Root>/conf/settings.xml中的<mirr ...
- select()函数用法一
select()函数用法以及FD_ZERO.FD_SET.FD_CLR.FD_ISSET select函数用于在非阻塞中,当一个套接字或一组套接字有信号时通知你,系统提供select函数来实现多路复用 ...
- 自定义ProgressBar的加载效果
三种方式实现自定义圆形页面加载中效果的进度条 To get a ProgressBar in the default theme that is to be used on white/light b ...
- 排序算法——Shell排序
二.Shell排序 Shell排序也叫“缩减增量排序”(disminishing increment sort),基于插入排序进行. Shell建议的序列是一种常用但不理想的增量序列:1,...,N/ ...
- Python生成器-博文读后感
Windows 10家庭中文版,Python 3.6.4, 上午看过了一篇讲Python生成器的博文: 提高你的Python: 解释‘yield’和‘Generators(生成器)’(英文原文) 这篇 ...
- 读书笔记--C陷阱与缺陷(四)
第四章 1. 连接器 C语言的一个重要思想就是分别编译:若干个源程序可在不同的时候单独进行编译,恰当的时候整合到一起. 连接器一般与C编译器分离,其输入是一组目标模块(编译后的模块)和库文件,输出是一 ...
- java8 - 3
import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.functio ...
- echart 打开新世界的大门
实时折线图 option = { backgroundColor:'#2B2B2B', tooltip: { trigger: 'axis' }, legend: { data:['频率'], tex ...
- s12-day01-work02 python多级菜单展示
README # README.md # day001-work-2 @南非波波 功能实现:多级菜单展示 流程图: ![](http://i.imgur.com/VTPPhZU.jpg) 程序实现: ...