hdu 6196 搜索+剪枝

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 阅读( ...) 评论( ...) 编辑 收藏
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值