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);
}
}