The child takes first and the person who gets more grade wins. The child will be happy only when he wins the game.
Bob wants to make the child happy, please help him calculate the minimal difference of their grades when he loses the game.
For each test case:
the first line only contains a number n (1≤n≤90&&n%2==0)
The second line contains n integers: a1,a2…an(1≤ai≤105).
题意:
给你长度为n的序列,爸爸和儿子玩一个游戏,儿子先手,儿子每次都选择最左边与最右边最大的那个拿走(若左右相等拿左边),爸爸可以任意拿最左边或者最右边。求爸爸输时的最小差是多少?
思路:
预处理区间的极值mx[l][r],mn[l][r]分别代表区间[l,r]间差值的最大值和最小值。在暴搜时用区间的极值来优化。可以用限定时间来限定搜索的深度。
推荐博客:http://blog.csdn.net/snowy_smile/article/details/77929954
//
// main.cpp
// 1003
//
// Created by zc on 2017/9/12.
// Copyright © 2017年 zc. All rights reserved.
//
#include <iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<time.h>
using namespace std;
template <class T1, class T2>inline void gmax(T1 &a,T2 b){ if(b>a) a=b;}
template <class T1, class T2>inline void gmin(T1 &a,T2 b){ if(b<a) a=b;}
const int N=100;
const int INF=0x3f3f3f3f;
int st,lim= 0 * CLOCKS_PER_SEC;
int n,a[N],mx[N][N],mn[N][N],ans;
void init()
{
memset(mx,-63,sizeof(mx));
memset(mn,63,sizeof(mn));
for(int i=1;i<=n+1;i++)
mx[i][i-1]=mn[i][i-1]=0;
for(int l=n;l>0;l--)
for(int r=l;r<=n;r++)
{
int ll=l,rr=r,son;
if(a[ll]>=a[rr]) son=a[ll++];
else son=a[rr--];
gmax(mx[l][r],mx[ll][rr-1]+a[rr]-son);
gmax(mx[l][r],mx[ll+1][rr]+a[ll]-son);
gmin(mn[l][r],mn[ll][rr-1]+a[rr]-son);
gmin(mn[l][r],mn[ll+1][rr]+a[ll]-son);
}
}
void dfs(int l,int r,int dif)
{
if(l>r)
{
if(dif<0) gmax(ans,dif);
return ;
}
if(mn[l][r]+dif>=0||mx[l][r]+dif<=ans) return ;
if(mx[l][r]+dif<0)
{
gmax(ans,mx[l][r]+dif);
return;
}
if(clock()-st>lim) return ;
int son;
if(a[l]>=a[r]) son=a[l++];
else son=a[r--];
dfs(l+1,r,dif+a[l]-son);
dfs(l,r-1,dif+a[r]-son);
}
int main(int argc, const char * argv[]) {
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
init();
st=clock();
ans=-INF;
dfs(1,n,0);
if(ans==-INF) puts("The child will be unhappy...");
else printf("%d\n",-ans);
}
}