uva 10891 - Game of Sum
2013-05-24 11:57
375 查看
import java.io.*; import java.math.BigInteger; import java.util.*; public class Main { public static void main (String [] args) throws Exception { Scanner scan = new Scanner(System.in); while(scan.hasNextInt()){ int n = scan.nextInt(); if(n==0) return; int arr[] = new int ; int sum[][] = new int ; for(int i=0;i<n;i++){ arr[i] = scan.nextInt(); } for(int i=0;i<n;i++){ sum[i][i] = arr[i]; for(int j=0;j<n;j++){ if(j==i) sum[i][j] = arr[i]; else if(j>i) sum[i][j] = sum[i][j-1]+arr[j]; else sum[i][j] = sum[i-1][j] + arr[i]; } } int dp[][] = new int[n+1][n+1]; for(int i=1;i<n+1;i++){ dp[i][i] = arr[i-1]; } for(int gap=1;gap<=n;gap++){ for(int i=1;i+gap<=n;i++){ int j=i+gap; int max = -99999999; for(int k=i;k<=j;k++){ max = Math.max(max, sum[i-1][j-1] - Math.min(dp[i][k], dp[k][j])); } dp[i][j] = max; } } System.out.println(2*dp[1] -sum[0][n-1]); } } }
usaco上A Game的变种,usaco上那题是一次在左边或者右边拿一个,这题是在左边或者右边拿一个或者多个。
无非是枚举这个多个到底是几个,取其中最大值。
解空间还是定义成dp[i][j],代表了能取到的最大值,那么dp[1]
就是从1到n能取到的最大值
公式呢就是dp[i][j] = max(sum[i][j] - min(dp[i][k], dp[k][j])); i<=k<=j;
由于我们存的是最大能取到的值,所以A能取到的值 = 总和 减掉 B能取到的值,
这里有一点绕,dp[i][k]和dp[k][j]都是B取到的最大值,区间不同。要让B取一个较小的,A才爽
在做这个博弈的时候我总是想分开存A和B的结果,其实A和B就是同一个情况。
貌似测试数据过了就过去了。。。1Y
相关文章推荐
- UVA 10891 Game of Sum dp(记忆化搜索)
- UVA - 10891 —— Game of Sum
- uva10891 Game of Sum(博弈+区间dp+优化)
- UVA10891 Game of Sum
- Uva 10891 Game of Sum(区间博弈dp)
- Game of Sum - UVa 10891 dp
- UVA 10891 Game of Sum(区间DP)
- uva 10891 - Game of Sum
- UVA 10891 Game of Sum(区间DP)
- UVa 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(经典博弈区间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 / 记忆化搜索
- [动态规划] Sum游戏 ( Game of Sum, Uva 10891 )