首页 > ACM题库 > UVA > Uva-10891-Game of Sum[动态规划]
2014
03-02

Uva-10891-Game of Sum[动态规划]

问题描述:

This is a two player game. Initially there are n integer numbers in an array and players A and B get chance to take them alternatively. Each player can take one or more numbers from the left or right end of the array but cannot take from both ends at a time. He can take as many consecutive numbers as he wants during his time. The game ends when all numbers are taken from the array by the players. The point of each player is calculated by the summation of the numbers, which he has taken. Each player tries to achieve more points from other. If both players play optimally and player A starts the game then how much more point can player A get than player B?

输入

The input consists of a number of cases. Each case starts with a line specifying the integer n (0 < n ≤100), the number of elements in the array. After that, n numbers are given for the game. Input is terminated by a line where n=0.

输出

For each test case, print a number, which represents the maximum difference that the first player obtained after playing this game optimally.

样例输入

4
4 -10 -20 7
4
1 2 3 4
0

样例输出

7
10

总和是一定的,所以一个人的得分越高,另一个人的得分越低。所以我们可以分析,另一个人在所能取得所有最优选择中得分最低的分数 m ,sum-m即为我的最高得分。

用d(i,j) 表示原 序列 [i...j] 在双方都采取最优的策略的情况下,先手得分的最大值。

对方肯定有一种可能是得0分,因为先手(先手是相对的,并不就是指第一个取的人)可以取完所有的。

d(i,j) = sum(i,j) – min{ d(i+1,j), d(i+2,j), … , d(j,j) , d(i,j-1), d(i,j-2), … , d(i,i) , 0 }

下面是Java记忆化搜索的代码:

import java.io.BufferedInputStream;
import java.util.Arrays;
import java.util.Scanner;

public class Uva_19461 {
	static int n, sum[] = new int[101];
	static int dp[][] = new int[101][101];
	static boolean vis[][] = new boolean[101][101];
	//记忆化搜索
	static int dp(int a,int b){
		if(vis[a][b]) return dp[a][b];
		vis[a][b] = true;
		int m = 0;
		for(int k=a+1; k<=b; k++) m = Math.min(m, dp(k,b) ); //枚举右半部分
		for(int k=a; k<b; k++) m = Math.min(m, dp(a,k) );//枚举左半部分
		dp[a][b] =  sum[b] - sum[a-1] - m ;
		return dp[a][b];
	}

	public static void main(String[] args) {
		Scanner s = new Scanner(new BufferedInputStream(System.in));
		while(true){
			n = s.nextInt();
			if(n == 0) break;
			sum[0] = 0;
			Arrays.fill(vis[0],false);
			for(int i=1; i<=n; i++){
				sum[i] = sum[i-1] +  s.nextInt();
				Arrays.fill(vis[i],false);
			}
			System.out.println(2*dp(1,n) - sum[n]);
		}

	}
}

  1. 网站做得很好看,内容也多,全。前段时间在博客园里看到有人说:网页的好坏看字体。觉得微软雅黑的字体很好看,然后现在这个网站也用的这个字体!nice!

  2. 其实国内大部分公司对算法都不够重视。特别是中小型公司老板根本都不懂技术,也不懂什么是算法,从而也不要求程序员懂什么算法,做程序从来不考虑性能问题,只要页面能显示出来就是好程序,这是国内的现状,很无奈。