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\n", ans);
	}
	return 0;
}

 

posted @ 2019-02-06 21:02  NKDEWSM  阅读(305)  评论(0编辑  收藏  举报