HDU 6196 happy happy happy (2017沈阳网赛 - 搜索 + dp + [黑科技。。。])

题意:

儿子和爸爸选牌, 每一次每个人只能从最左边选择或者在最右边选择, 儿子的决策是 选左边 和 右边最大的那个位置, 如果一样大, 选择左边, 爸爸的决策是为了让儿子赢, 问你 如果儿子能赢 爸爸与儿子的最小分数差是多少, 如果无论如和 爸爸都赢儿子 输出The child will be unhappy...

思路:

很乱搞的一个题目。。

我们先预处理出两个dp 来, dp1[i][j]表示 i~j 这个区间 儿子先手 爸爸拿牌的最小值,

dp2[i][j] 则表示i~j 这个区间儿子先手, 爸爸拿牌的最大值。

有了两个dp 就可以搜索了。

dfs(l,r,dif) 表示搜索l~r 这个区间, 目前爸爸减儿子的分数为dif。

然后dfs里模拟儿子和爸爸就行了, 儿子直接按照贪心来, 爸爸 的话 就都搜一遍。

dfs里得加点剪枝。

如果目前dif + dp1(最小值) >= 0 的话, 肯定是爸爸赢儿子了 return掉。

如果dif + dp2 还不如 ans(目前最优解), 也剪掉。

如果选择dp2 还小于0 就更新一下答案, 也没必要继续搜了。

当然感觉这些都没啥卵用。。

加一个小黑科技, 看到快超时时, 直接return好了。

    if (clock() - ST > LIM) {
        return;
    }



#include 
#include 
#include 
#include 
using namespace std;

const int maxn = 100;
const int inf = 0x3f3f3f3f;
int a[maxn];
int dp1[maxn][maxn], dp2[maxn][maxn], sum[maxn];
int ST;
int LIM = 0 * CLOCKS_PER_SEC;
int DP1(int l,int r){
    int& ans = dp1[l][r];
    if (ans != -1) return ans;

    if (l > r) {
        return ans = 0;
    }
    if (a[l] >= a[r]){
        ans = min(DP1(l + 1, r - 1) + a[r], DP1(l + 2, r) + a[l + 1]);
    }
    else {
        ans = min(DP1(l+1, r-1) + a[l], DP1(l, r-2) + a[r-1]);
    }
    return ans;
}
int DP2(int l,int r){
    int& ans = dp2[l][r];
    if (ans != -1) return ans;

    if (l > r) {
        return ans = 0;
    }
    if (a[l] >= a[r]){
        ans = max(DP2(l + 1, r - 1) + a[r], DP2(l + 2, r) + a[l + 1]);
    }
    else {
        ans = max(DP2(l+1, r-1) + a[l], DP2(l, r-2) + a[r-1]);
    }
    return ans;
}


int ans;

void dfs(int l,int r,int dif){
    if (l > r){
        ans = max(ans, dif);
        return;
    }
    if (dif + 2 * dp1[l][r] - (sum[r] - sum[l-1]) >= 0) return;
    if (dif + 2 * dp2[l][r] - (sum[r] - sum[l-1]) <= ans) return;
    if (dif + 2 * dp2[l][r] - (sum[r] - sum[l-1]) < 0){
        ans = max(ans, dif + 2 * dp2[l][r] - (sum[r] - sum[l-1]));
        return;
    }
    if (clock() - ST > LIM) { /// 醉了。。
        return;
    }
    if (a[l] >= a[r]){
        dfs(l + 1, r - 1, dif + a[r] - a[l]);
        dfs(l + 2, r, dif + a[l + 1] - a[l]);
    }
    else {
        dfs(l, r - 2, dif + a[r-1] - a[r]);
        dfs(l + 1, r - 1, dif + a[l] - a[r]);
    }
}
int main(){
    int n;
    while(~scanf("%d", &n)){
        for (int i = 1; i <= n; ++i){
            scanf("%d", a + i);
            sum[i] = sum[i-1] + a[i];
        }
        ST = clock();
        memset(dp1,-1,sizeof dp1);
        memset(dp2,-1,sizeof dp2);
        DP1(1, n); DP2(1, n);
        ans = -inf;
        dfs(1, n, 0);
        ans = -ans;
        if (ans >= inf){
            puts("The child will be unhappy...");
        }
        else {
            printf("%d\n", ans);
        }
    }


    return 0;
}

happy happy happy

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 530    Accepted Submission(s): 157


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...
 

Source
2017 ACM/ICPC Asia Regional Shenyang Online
 

Recommend
liuyiding   |   We have carefully selected several similar problems for you:   6205  6204  6203  6202  6201 
 




你可能感兴趣的:(DFS,HDU,DP)