【2017沈阳网络赛】1003 hdu6196 happy happy happy 暴搜+区间dp+卡时优化

Problem Description
Today, Bob plays with a child. There is a row of n numbers. One can takes a number from the left side or the right side in turns and gets the grade which equals to the number. Bob knows that the child always chooses the bigger number of the left side and right side. If the number from two sides is equal, child will always choose the left one.
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. 
 

Input
There are T test cases (T2).
For each test case: 
the first line only contains a number n (1n90&&n%2==0
The second line contains n integers: a1,a2an(1ai105).
 

Output
For each test ease, you should output the minimal difference of their grades when Bob loses the game. If Bob can't lose the game, output "The child will be unhappy...".
 

Sample Input
4 2 1 5 3 2 2 2
 

Sample Output
5 The child will be unhappy...
 


题意:

给你长度为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);
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章