sdnu 1261.Problem J. Alice and Bob II 巧妙地dfs+dp用法;

1261.Problem J. Alice and Bob II

Time Limit: 1000 MS    Memory Limit: 32768 KB
Total Submission(s): 3    Accepted Submission(s): 2

Description

Alice have a friend Bob, they both smart,Today they are going to play a new game again

a.  There are N heap stones here

b.  They took stones in turn

c.  Only take stones from both ends, take a heap each time

d.  Alice first

Input

The first line is T, T is TestCase(0 < T <= 1000)

The first line of each testcase is a number N, M(0 < n <= 100,)

The next line each contain N integers x  indicating the number of each heap . (1 ≤ x ≤  1000)

Output

Case #TestCase: answer

Answer is the most stones Alice got

Sample Input

141 2 3 4

Sample Output

Case #1:  6

Source

Unknown

            这道题~大体意思就是Alice和一个人分别拿石子~~每次每人可以从两端中的一选一堆拿走~双方都绝顶聪明~~在Alice先手的情况下,Alice最多能拿到多少堆;

            这道题要用dp来创造一个辅助数组dp,dp[l][r]表示在在剩下的l到r堆石子的情况下~Alice能拿到的最多的石子数量。

            然后就用dfs进行深度优先搜索~~,l,r表示现在的剩下的石子堆数情况~cnt用来看现在是谁要动手了~~

            假如现在是Alice开始了(cnt%2==1)~~那么一共就是两种情况:从左边开始拿~再加上剩下的区间他能拿到的最大值;;再就是从右边开始拿~再加上左边区间他能拿到的最大值----------但是如果现在是对手的回合(cnt)~~那就不一样了~~

对手会有两个选择::拿左边的,让A拿右边的::拿右边的,让A拿左边的~~但是最后~~他会让A拿到区间值最小的。dfs的最后就是当l===r的时候~~看现在谁的回合来判定~~

#include
#include
#include
using namespace std;
int m[105];
int dp[105][105];
int ans;
int dfs(int l, int r, int cnt)
{
	//cout << l << " " << r << endl;
	if (l == r)
	{
		if (cnt % 2)
		{
			return m[l];
		}
		else
		{
			return 0;
		}
	}
	if (dp[l][r] != 0)
	{
		return dp[l][r];
	}
	else
	{
		int e;
		e = cnt % 2 == 1 ? 1 : 0;
		if (e)
		{
			int a1 = 0;
			a1 += m[l] + dfs(l + 1, r, cnt + 1);
			int a2 = 0;
			a2 += m[r] + dfs(l, r - 1, cnt + 1);
			dp[l][r] = a1 > a2 ? a1 : a2;
			return dp[l][r];
		}
		else
		{
			int a1 = 0;
			a1 = dfs(l + 1, r, cnt + 1);
			int a2 = 0;
			a2 = dfs(l, r - 1, cnt + 1);
			dp[l][r] = a1 < a2 ? a1 : a2;
		//	cout << l << " " << r << " " << dp[l][r] << endl;
			return dp[l][r];
		}
	}
}
int main()
{
	int te;
	scanf("%d", &te);
	int t = 1;
	while (te--)
	{	
		int n;
		scanf("%d", &n);
		memset(dp, 0, sizeof(dp));
		ans = 0;
		for (int s = 1; s <= n; s++)
		{
			scanf("%d", &m[s]);
		}
		for (int s = 1; s <= n; s++)
		{
			dp[s][s] = m[s];
		}
		printf("Case #%d: %d\n", t++, dfs(1, n, 1));
	}
	return 0;
}




你可能感兴趣的:(dp)