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

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