动态规划-猜石头

你和你的朋友面前有一排石头堆,用一个数组 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

posted @ 2020-07-24 14:06  使用D  阅读(244)  评论(0编辑  收藏  举报