zoukankan      html  css  js  c++  java
  • 动态规划-1620. 收集硬币

    2020-04-08 07:45:18

    问题描述:

    给定一个n * m个的矩阵,矩阵的每个位置有一定数量的硬币,你从(0,0)位置出发,每次只能往右或者往下走,当他经过某个格子的时候,可以得到这个格子上的所有硬币,当它走到第(n-1,M-1)位置时游戏结束,在游戏开始前,你有ķ次机会,可以交换某两个格子中的硬币数量中,k次机会不一定要使用完,求从(0,0)走到第(n-1,M-1)所能得到的最大的硬币数量。

    样例

    输入:
    matrix = [[9,9,9,0,0],[0,0,9,0,0],[0,0,0,0,0],[0,0,9,0,0],[9,0,9,9,9]]
    k = 1
    输出:81

    注意事项

    • 2≤n,m≤50
    • 0<=k<=20
    • 0<=matrix[I][j]<=1000000

    问题求解:

        int nums[55];
        int dp[55][55][25][25];
        int collectingCoins(vector<vector<int>> &matrix, int k) {
            // Write your code here
            int n = matrix.size();
            int m = matrix[0].size();
            memset(dp, -0x3f,sizeof(dp));
            dp[0][0][0][0] = matrix[0][0], dp[0][0][0][1] = 0;
            for(int x = 0; x < n; x++) {
                for(int y = 0; y < m; y++) {
                    if (x == 0 && y == 0) continue;
                    int idx = 0;
                    if(x) {
                        for(int j = y + 1; j < m; j++) {
                            nums[idx++] = matrix[x - 1][j];
                        }
                    }
                    for(int j = 0; j < y; j++) {
                        nums[idx++] = matrix[x][j];
                    }
                    sort(nums,nums + idx,greater<int>());
                    for(int used = 0; used <= k;used ++)
                    {
                        for(int blank = 0;blank <= x + y + 1 && blank <= k; blank++)
                        {
                            int res = INT_MIN;
                            if(x) {
                                res = max(res, dp[x - 1][y][used][blank] + matrix[x][y]);
                                if(blank) 
                                {
                                    res = max(res,dp[x - 1][y][used][blank - 1]);
                                }
                                int sum = 0;
                                int it = 0;
                                for(int cntuse = 1;cntuse <= used && cntuse <= idx;cntuse ++)
                                {
                                    sum += nums[it++];
                                    res = max(res,dp[x - 1][y][used - cntuse][blank] + matrix[x][y] + sum);
                                    if(blank) 
                                    {
                                        res = max(res,dp[x - 1][y][used - cntuse][blank - 1] + sum);
                                    }
                                }
                            }
                            if(y)
                            {
                                res = max(res,dp[x][y - 1][used][blank] + matrix[x][y]);
                                if(blank) 
                                {
                                    res = max(res,dp[x][y - 1][used][blank - 1]);
                                }
                            }
                            dp[x][y][used][blank] = res;
                        }
                    }
                }
            }
            int res = 0;
            for(int i = 0;i <= k; i++) {
                res = max(res,dp[n - 1][m - 1][i][i]);
            }
            return res;
        }
    

      

  • 相关阅读:
    左偏树
    “今日头条杯”首届湖北省大学程序设计竞赛现场赛
    最短路
    BP神经网络算法改进
    图论学习路线
    差分演化算法
    51Nod 1413 权势二进制
    51Nod 1315 合法整数集
    Treap(树堆)
    今日头条杯2018湖北省大学生程序设计竞赛(网络赛)
  • 原文地址:https://www.cnblogs.com/hyserendipity/p/12657660.html
Copyright © 2011-2022 走看看