“不要因为错过夕阳而哭泣,那样你将失去更美丽的夜空。”——泰戈尔
题目
给你一个由正整数构成的二维矩阵 grid
。
你需要从矩阵中选择 一个或多个 单元格,选中的单元格应满足以下条件:
- 所选单元格中的任意两个单元格都不会处于矩阵的 同一行。
- 所选单元格的值 互不相同。
你的得分为所选单元格值的总和。
返回你能获得的 最大 得分。
难度:困难
分析
笔者知道该怎么做,但是修Bug修了一个多小时还没修出来😫,重整旗鼓终于把毛病揪出来了,蓝瘦香菇。
首先对矩阵预处理:对于同一行的值,优先考虑最大的值,所以进行降序排序。对于相同的值,因为只能选一个,所以只用存一个值就行。每次开始,比较每个未取过值的行的最大值(除去别的行已经用过的值),如果最大值只有一个,则直接选取;如果有多个,则通过回溯取不同行得到的结果取最大值(不知道有没有贪心的方法)。
修Bug小记:如果是引用传值,每次调用dfs结束后要把置为1的值重置为0!
解答
class Solution {
public:
int m;
int maxScore(vector<vector<int>>& grid) {
m=grid.size();
int n=grid[0].size();
vector<vector<int>> matrix(m);
for (int i=0;i<m;i++){
vector<int> used(101);
for (int j=0;j<n;j++){
int x=grid[i][j];
if (used[x]==0){
matrix[i].push_back(x);
used[x]=1;
}
}
}
for (int i=0;i<m;i++){
sort(matrix[i].begin(),matrix[i].end(),greater<int>());
}
vector<int> index(m);
vector<int> usedRow(m);
return dfs(matrix,index,usedRow);
}
int dfs(vector<vector<int>>& matrix, vector<int>& index, vector<int>& usedRow){
vector<int> maxRow;
int maxNum=0;
for (int i=0;i<m;i++){
if (usedRow[i]==0&&index[i]<matrix[i].size()){
int cur=matrix[i][index[i]];
if (cur>maxNum){
maxRow={i};
maxNum=cur;
}else if (cur==maxNum){
maxRow.push_back(i);
}
}
}
if (maxRow.empty()){
return 0;
}else if (int(maxRow.size())==1){
usedRow[maxRow[0]]=1;
int cur=dfs(matrix,index,usedRow);
usedRow[maxRow[0]]=0;
return maxNum+cur;
}else{
int ans=maxNum;
for (int i:maxRow){
index[i]++;
}
for (int i:maxRow){
usedRow[i]=1;
int cur=maxNum+dfs(matrix,index,usedRow);
ans=max(ans,cur);
usedRow[i]=0;
}
for (int i:maxRow){
index[i]--;
}
return ans;
}
}
};