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; }
来源:https://www.cnblogs.com/hyserendipity/p/12657660.html