zoukankan      html  css  js  c++  java
  • 动态规划-猜石头

    你和你的朋友面前有一排石头堆,用一个数组 piles 表示,piles[i] 表示第 i 堆石子有多少个。你们轮流拿石头,一次拿一堆,但是只能拿走最左边或者最右边的石头堆。所有石头被拿完后,谁拥有的石头多,谁获胜。

    石头的堆数可以是任意正整数,石头的总数也可以是任意正整数,这样就能打破先手必胜的局面了。比如有三堆石头 piles = [1,100,3],先手不管拿 1 还是 3,能够决定胜负的 100 都会被后手拿走,后手会获胜。

    假设两人都很聪明,请你设计一个算法,返回先手和后手的最后得分(石头总数)之差。比如上面那个例子,先手能获得 4 分,后手会获得 100 分,你的算法应该返回 -96。

     

        public static void main(String[] args) {
            testA();
        }
    
        static class NodeA {
            private int first;
            private int second;
    
            public NodeA(int first, int second) {
                this.first = first;
                this.second = second;
            }
    
            public String toString() {
                return "(" + first + " ," + second + ")";
            }
        }
    
        /**
         * a为整数数组,A与B两人分别从a最前或者最后拿元素,A先手与后手分别拿的合集合计
         */
        public static void testA() {
            int[] a = {3, 9, 1, 2, 1};
            //定义dp二维数组
            NodeA[][] dp = new NodeA[a.length][a.length];
            //初始化值
            for (int i = 0; i < a.length; i++) {
                for (int j = 0; j < a.length; j++) {
                    if (i == j) {
                        dp[i][j] = new NodeA(a[i], 0);
                    } else {
                        dp[i][j] = new NodeA(0, 0);
                    }
                }
            }
            for (int i = 0; i < a.length; i++) {
                for (int j = 0; j < a.length; j++) {
                    System.out.print(dp[i][j].toString());
                }
                System.out.println();
            }
            //动态转移公式
            //dp[i][j]=max( a[i] + dp[i+1][j], a[j] + dp[i][j-1])
            for (int i = 0; i < a.length; i++) {
                for (int j = i; j < a.length; j++) {
                    if (i != j) {
                        int first = 0;
                        int second = 0;
                        first = Math.max(a[i] + dp[i + 1][j].second, a[j] + dp[i][j - 1].second);
                        if (a[i] + dp[i + 1][j].second >= a[j] + dp[i][j - 1].second) {
                            dp[i][j] = new NodeA(first, dp[i + 1][j].first);
                        } else {
                            dp[i][j] = new NodeA(first, dp[i][j - 1].first);
                        }
                    }
                }
            }
            for (int i = 0; i < a.length; i++) {
                for (int j = 0; j < a.length; j++) {
                    System.out.print(dp[i][j].toString());
                }
                System.out.println();
            }
        }

    算法参考:https://mp.weixin.qq.com/s?__biz=MzAxODQxMDM0Mw==&mid=2247484496&amp;idx=1&amp;sn=d04bb89cb1df241993c6b46ffcabae7e&source=41#wechat_redirect

  • 相关阅读:
    Java MQTT 客户端之 Paho
    Spring Security + JJWT 实现 JWT 认证和授权
    MinIO
    Spring Boot 实现看门狗功能 (调用 Shell 脚本)
    Canal Admin
    canal
    浅尝 Elastic Stack (五) Logstash + Beats + Kafka
    养鸡场下蛋记
    涛声依旧
    原创:矩阵论学习心得
  • 原文地址:https://www.cnblogs.com/use-D/p/13371595.html
Copyright © 2011-2022 走看看