蓝桥杯 算法训练 逗志芃的危机(Java)

问题描述
  逗志芃又一次面临了危机。逗志芃的妹子是个聪明绝顶的人,相比之下逗志芃就很菜了。现在她妹子要和他玩一个游戏,这个游戏是这样的:一共有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. 观察题目,我们可以知道男生是第一个拿的并且他必须要拿大的一个数,因此我们建立了一个二维数组,外层循环从大到小,而内层是由等于外层开始每次累加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{
            ..................
}
  1. 先来单独的分析这里的代码,满足else条件的位置有:

33 ->无
22 -> 23
11 -> 12、13
00 -> 01、02、03

结合表格来看就是这几个位置会有数据被填入(当然二维数组在new的时候已经附上初始值的了为0,这里和一下出现的表格都不标上方便查看):

  1. 在这里的坐标之差我们可以理解为:当为奇数的时候就是由男生选(并且是最大的)

而为偶数时,就是到女生选了,女生也不傻肯定选最大的,侧面则是说明男生选了两个大的小的那个

if (((j - i) & 1) == 1)
  1. 一步一步分析:(2,3)这里是男生第一次取数的位置,毫无疑问他肯定是取最大的那个。

结合代码可以得到:

aa[i][j] = Math.max(aa[i+1][j] + a[i],aa[i][j-1]+a[j]);

下面就到(1,2)了 同理可得:

而下一个到(1,3)这个时候3-1为偶数,则男生这两个中小的那个:

同理到(0,1)~(0,3)时,我们可以得到:

而(0,3)就是我们需要求的答案了。

综上所述: 从倒数一个数开始分别与后面一个数来比较,为奇数时男生拿最大,为偶数时拿最小,那么最后男生的结果就会比女生的大了,也就是局部最优解->全局最优解的动态规划问题。

测试结果:

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Luca-s-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值