问题描述
逗志芃又一次面临了危机。逗志芃的妹子是个聪明绝顶的人,相比之下逗志芃就很菜了。现在她妹子要和他玩一个游戏,这个游戏是这样的:一共有n个数(n是偶数)写成一行,然后两个人轮流取数,每次只能从最前面或者最后面取走一个数,全部取完则游戏结束,之后每个人取走的数的和就是每个人的得分。由于逗志芃妹子很厉害,但他又不想输,所以只能找到你了,你要告诉他最多可以得到多少分。(注意,妹子智商是maxlongint所以是不会犯错的,每次的策略必然最优,而且逗志芃是先手)
输入格式
第一行一个数n,表示有n个数。
第二行就是进行游戏的n个数。
输出格式
一个数,最高得分
样例输入
2
10 20
样例输出
20
数据规模和约定
例:0<n,m<=1000,每个数不超过10000 。
完整代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] a = new int[n];
int[][] aa = new int[n][n];
for (int k = 0; k < n; k++){
a[k] = sc.nextInt();
}
for (int i = n-1; i >= 0; i--){
for (int j = i; j < n; j++){
if (i == j ){
aa[i][j] = 0;
}else
{
if (((j - i) & 1) == 1){
aa[i][j] = Math.max(aa[i+1][j] + a[i],aa[i][j-1]+a[j]);
}else {
aa[i][j] = Math.min(aa[i+1][j],aa[i][j-1]);
}
}
}
}
System.out.println(aa[0][n-1]);
}
}
思路来源与代码借鉴:https://blog.csdn.net/fuzekun/article/details/127355949
思路:
观察题目,我们可以知道男生是第一个拿的并且他必须要拿大的一个数,因此我们建立了一个二维数组,外层循环从大到小,而内层是由等于外层开始每次累加1进行赋值。以本例子进行分析:
4
12 10 16 20 答案:32
数组元素: | 12 | 10 | 16 | 20 |
元素角标: | 0 | 1 | 2 | 3 |
for (int i = n-1; i >= 0; i--){
for (int j = i; j < n; j++){
if (i == j ){
aa[i][j] = 0;
}else{
..................
}
先来单独的分析这里的代码,满足else条件的位置有:
33 ->无
22 -> 23
11 -> 12、13
00 -> 01、02、03
结合表格来看就是这几个位置会有数据被填入(当然二维数组在new的时候已经附上初始值的了为0,这里和一下出现的表格都不标上方便查看):
![](https://img-blog.csdnimg.cn/img_convert/46db7f3fa9c249da8ab2764169481765.png)
在这里的坐标之差我们可以理解为:当为奇数的时候就是由男生选(并且是最大的)
而为偶数时,就是到女生选了,女生也不傻肯定选最大的,侧面则是说明男生选了两个大的小的那个
if (((j - i) & 1) == 1)
一步一步分析:(2,3)这里是男生第一次取数的位置,毫无疑问他肯定是取最大的那个。
结合代码可以得到:
aa[i][j] = Math.max(aa[i+1][j] + a[i],aa[i][j-1]+a[j]);
![](https://img-blog.csdnimg.cn/img_convert/353f4dca9be82e6a01cf64515c36a8b8.png)
下面就到(1,2)了 同理可得:
![](https://img-blog.csdnimg.cn/img_convert/b7937a1b9adc9b5a354242035f996767.png)
而下一个到(1,3)这个时候3-1为偶数,则男生这两个中小的那个:
![](https://img-blog.csdnimg.cn/img_convert/69a72316a0119617c17db6cd05ffc220.png)
同理到(0,1)~(0,3)时,我们可以得到:
![](https://img-blog.csdnimg.cn/img_convert/6e56508c8ab384b42ace93aa2dc0abe5.png)
而(0,3)就是我们需要求的答案了。
综上所述: 从倒数一个数开始分别与后面一个数来比较,为奇数时男生拿最大,为偶数时拿最小,那么最后男生的结果就会比女生的大了,也就是局部最优解->全局最优解的动态规划问题。
测试结果:
![](https://img-blog.csdnimg.cn/img_convert/095fb5c8db54f782abc28df111a40908.png)