技巧:
贪心(两个维度 改变会影响前后),需要用枚举办法固定一个维度 然后贪心的选择另外一个维度。
思路:
用01串模拟要不要当前行(枚举)
在行固定的情况下贪心选最优的列 并更新结果
实现:
package main import ( "fmt" ) var ans int func main() { // Input var n, m, k int fmt.Scan(&n, &m, &k) arr := make([][]int, n) for i := 0; i < n; i++ { arr[i] = make([]int, m) for j := 0; j < m; j++ { fmt.Scan(&arr[i][j]) } } process(arr, n, m, k) fmt.Println(ans) } // 枚举(n) + 贪心(m) func process(arr [][]int, n, m, k int) { tmp := 1 << n for i := 0; i < tmp; i++ { cnt := get1Cnt(i) if k < cnt { continue } sum := 0 // 1 计算行的总和 for row := 0; row < n; row++ { if (i>>row)&1 == 1 { // 该位若是1 代表选了这行 for j := 0; j < m; j++ { sum += arr[row][j] } } } // 2 计算列的总和 取得前 colK 大的前缀和 colK := k - cnt // 剩余给列操作的次数 colSumArr := make([]int, colK) for col := 0; colK > 0 && col < m; col++ { currColSum := 0 for row := 0; row < n; row++ { if (i>>row)&1 == 0 { currColSum += arr[row][col] } } // 利用插入排序思想只保存前K组和最大的列 if currColSum > colSumArr[colK - 1] { colSumArr[colK-1] = currColSum } for j := colK - 1; j > 0 && colSumArr[j] > colSumArr[j-1]; j-- { colSumArr[j], colSumArr[j-1] = colSumArr[j-1], colSumArr[j] } } for _, v := range colSumArr { sum += v } // 3 更新结果 if sum > ans { ans = sum } } } // 获取1的数量 func get1Cnt(x int) int { cnt := 0 for x != 0 { if x&1 == 1 { cnt++ } x >>= 1 } return cnt }