UVA - 10891 Game of Sum

题目大意:有n个数字排成一条直线,然后有两个小伙伴来玩游戏, 每个小伙伴每次可以从两端(左或右)中的任意一端取走一个或若干个数(获得价值为取走数之和), 但是他取走的方式一定要让他在游戏结束时价值尽量的高,最头疼的是两个小伙伴都很聪明,所以每一轮两人都将按照对自己最有利的方法去取数字,请你算一下在游戏结束时,先取数的人价值与后取数人价值之差(不要求绝对值)。


解题思路:dpx[i][j]表示在当前第i个数到第j个数中先取数的人可以达到的最高价值, dpy[i][j]为后取者最高可以达到的最高值。每次根据传入的参数flag判断是该谁去石子, 通过引用返回最优解。


注意:数字可以为负数,所以标记的时候要注意


#include <iostream>
#include <cstring>
using namespace std;
int sum[105] = {0}, DP[105][105];

int DPS(int i, int j) {
	int mi = 0;
	if (DP[i][j])
		return DP[i][j];
	for (int k = i; k < j; k++) {
		mi = min(DPS(i, k), mi);
		mi = min(DPS(k + 1, j), mi);
	}
	return DP[i][j] = sum[j] - sum[i-1] - mi;
}

int main() {
	int n;
	while (cin >> n && n) {
		memset(DP, 0, sizeof(DP));
		for (int i = 1; i <= n; i++) {
			cin >> sum[i];
			sum[i] += sum[i-1];
		}

		cout << 2 * DPS(1, n) - sum[n] << endl;
	}
	return 0;
} 


你可能感兴趣的:(UVA - 10891 Game of Sum)