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
  • 相关阅读:
    守望先锋2中源氏皮肤变化
    博客园页面定制设置背景
    京剧中的“八句唱法”
    长歌行
    长相知-《上邪》-汉乐府
    Eclipse离线安装svn插件
    不安装Oracle客户端,用PLSQL连接Oracle
    常见数据库默认端口以及常用数据类型
    Python2.7 删除前N天日志文件
    Anaconda用conda创建python虚拟环境
  • 原文地址:https://www.cnblogs.com/zxyqzy/p/10354075.html
Copyright © 2011-2022 走看看