UVA - 10891 Game of Sum
2015-03-16 19:50
281 查看
题目大意:有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
<< endl;
}
return 0;
}
解题思路: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
<< endl;
}
return 0;
}
相关文章推荐
- UVA 10891 Game of Sum(区间DP)
- UVA 10891 Game of Sum 博弈DP -
- uva 10891 game of sum
- UVA 10891 Game of Sum
- UVa 10891 Game of Sum (区间DP&博弈)
- uva 10891 - Game of Sum
- UVA - 10891 —— Game of Sum
- uva10891 Game of Sum(博弈+区间dp+优化)
- UVA 10891 Game of Sum(区间博弈dp)***
- uva10891 - Game of Sum(递推,极大极小的思想)
- UVA 10891 Game of Sum(区间DP)
- [动态规划] Sum游戏 ( Game of Sum, Uva 10891 )
- uva 10891 game of sum
- uva10891 Game of Sum 博弈区间dp
- UVa10891 Game of Sum(dp)
- UVA 10891 Game of Sum
- UVa 10891 Game of Sum
- UVA 10891 Game of Sum(区间DP)
- UVA 10891 Game of Sum(区间DP)
- UVA 10891——Game of Sum