UVA 10891 Game of Sum

81 篇文章 1 订阅

用S(i)表示前缀和

用f(i, j)代表从序列i到j先手能得到最大值.

则方程就是f(i, j) = S(j) - S(i) - min( min{f(i + 1, j) .. f(j ,j)}//从右往左, min{f(i,i), f(i, i + 1), ... f(i, j - 1)} //从左往右)

/*
 * UVA10891.cpp
 *
 *  Created on: Jun 4, 2013
 *      Author: root
 */
#include <iostream>
#include <cstdio>
#include <memory.h>
using namespace std;
const int maxn = 105;

bool vis[maxn][maxn];
int f[maxn][maxn],S[maxn];
int n;

int dp(int i, int j){
	if(vis[i][j])return f[i][j];
	vis[i][j] = 1;
	int minv = 0;
	for(int k = i + 1; k <= j; ++k)minv = min(minv, dp(k, j));
	for(int k = i; k < j; ++k)minv = min(minv, dp(i, k));
	return f[i][j] = S[j] - S[i - 1] - minv;;
}
int main(){
	while(scanf("%d", &n) && n){
		memset(vis, 0, sizeof(vis));
		for(int i = 1; i <= n; ++i){
			int t;
			scanf("%d", &t);
			S[i] = S[i - 1] + t;
		}
		int ret = dp(1, n);
		printf("%d\n", ret - (S[n] - ret));
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值