zoukankan      html  css  js  c++  java
  • hdu 6196 搜索+剪枝

    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.
    InputThere 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).
    OutputFor 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...

    Child每次取最大的,如果相等就取左边的;
    那么我们可以记忆化搜索出[L,R]区间的按游戏规则的可以取到的最大值和最小值;
    df 表示 Grade_bob - Grade_child 的值;
    如果df+dpmin[L,R]>0,那么剪去;
    如果df+dpmax[L,R]<=ans,剪去;
    如果df+dpmax[L,R]<0,更新,return;
    然后就是搜索了,
    (卡时也是秀)
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<map>
    #include<set>
    #include<vector>
    #include<queue>
    #include<bitset>
    #include<ctime>
    #include<time.h>
    #include<deque>
    #include<stack>
    #include<functional>
    #include<sstream>
    //#include<cctype>
    //#pragma GCC optimize(2)
    using namespace std;
    #define maxn 200005
    #define inf 0x7fffffff
    //#define INF 1e18
    #define rdint(x) scanf("%d",&x)
    #define rdllt(x) scanf("%lld",&x)
    #define rdult(x) scanf("%lu",&x)
    #define rdlf(x) scanf("%lf",&x)
    #define rdstr(x) scanf("%s",x)
    #define mclr(x,a) memset((x),a,sizeof(x))
    typedef long long  ll;
    typedef unsigned long long ull;
    typedef unsigned int U;
    #define ms(x) memset((x),0,sizeof(x))
    const long long int mod = 1e9;
    #define Mod 1000000000
    #define sq(x) (x)*(x)
    #define eps 1e-5
    typedef pair<int, int> pii;
    #define pi acos(-1.0)
    //const int N = 1005;
    #define REP(i,n) for(int i=0;i<(n);i++)
    typedef pair<int, int> pii;
    
    inline int rd() {
    	int x = 0;
    	char c = getchar();
    	bool f = false;
    	while (!isdigit(c)) {
    		if (c == '-') f = true;
    		c = getchar();
    	}
    	while (isdigit(c)) {
    		x = (x << 1) + (x << 3) + (c ^ 48);
    		c = getchar();
    	}
    	return f ? -x : x;
    }
    
    
    ll gcd(ll a, ll b) {
    	return b == 0 ? a : gcd(b, a%b);
    }
    int sqr(int x) { return x * x; }
    
    
    
    /*ll ans;
    ll exgcd(ll a, ll b, ll &x, ll &y) {
    	if (!b) {
    		x = 1; y = 0; return a;
    	}
    	ans = exgcd(b, a%b, x, y);
    	ll t = x; x = y; y = t - a / b * y;
    	return ans;
    }
    */
    int n;
    int a[maxn];
    int sum[maxn];
    int dp1[200][200], dp2[200][200];
    int ST;
    int Lim = 0.00045 * 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 df) {
    	if (l > r) {
    		ans = max(ans, df); return;
    	}
    	if (df + 2 * dp1[l][r] - (sum[r] - sum[l - 1]) >= 0)return;
    	if (df + 2 * dp2[l][r] - (sum[r] - sum[l - 1]) <= ans)return;
    	if (df + 2 * dp2[l][r] - (sum[r] - sum[l - 1]) < 0) {
    		ans = max(ans, df + 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, df + a[r] - a[l]);
    		dfs(l + 2, r, df + a[l + 1] - a[l]);
    	}
    	else {
    		dfs(l + 1, r - 1, df + a[l] - a[r]);
    		dfs(l, r - 2, df + a[r - 1] - a[r]);
    	}
    }
    int main()
    {
    //	ios::sync_with_stdio(0);
    
    	while (cin >> n) {
    		ms(a); ms(sum);
    		for (int i = 1; i <= n; i++)a[i] = rd(), sum[i] = sum[i - 1] + a[i];
    
            ST = clock();
    		mclr(dp1, -1); mclr(dp2, -1);
    		DP1(1, n); DP2(1, n);
    		ans = -inf;
    		dfs(1, n, 0);
    		ans = abs(ans);
    		if (ans >= inf) {
    			puts("The child will be unhappy...");
    		}
    		else printf("%d
    ", ans);
    	}
    	return 0;
    }
    
    EPFL - Fighting
  • 相关阅读:
    YOLOv5实现自定义对象训练与OpenVINO部署全解析
    GMS程序调试指南GMS-Feature-Matcher
    MobileNet V3与Lite R-ASPP 总结
    codevs 3385 拯救Oier(一) Save Oier—first
    喵哈哈村的魔法考试 Round #6 (Div.3) 题解
    POJ 1852 Ants
    加强赛第一轮题解
    喵哈哈村的魔法考试 Round #3 (Div.2)
    python小数据池,代码块的最详细、深入剖析
    比较三个数的大小
  • 原文地址:https://www.cnblogs.com/zxyqzy/p/10354075.html
Copyright © 2011-2022 走看看