Indeed修改数组行或者列,得到最大数组和
来源:互联网 发布:淘宝等级图 编辑:程序博客网 时间:2024/05/21 18:48
输入
H,W,X,K
int[H][W]
H代表行,W代表列,X代表要替换成的数字,k代表要替换多少行或者列(替换的行列数之和可以小于K).
输出:
各种替换可能中,数组的最大和。
例子:
输入:
8
8
29
14
-89 -76 92 61 5 -18 -68 90
-3 44 -9 84 -36 51 -43 85
11 -72 5 -90 -43 -94 5 97
-90 22 66 29 -26 66 -29 -38
82 -60 60 -9 -23 -8 -59 -13
-4 -68 -4 59 78 25 99 -86
-4 23 21 53 53 -25 -31 -66
38 50 -35 -98 -49 -33 -31 88
output:2100
输入:
3
4
3
2
1 -1 1 1
5 -5 5 5
9 -9 9 9
输出:
60
一开始的想法是直接贪心。每次替换最大增量的行或者列:
代码如下:
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.HashSet;import java.util.Scanner;import java.util.Set;public class Main {private int H;private int W;private int X;private int K;private int[][] arr;private int sumR[];private int sumC[];public Main() {Scanner sc = new Scanner(System.in);H = sc.nextInt();W = sc.nextInt();X = sc.nextInt();K = sc.nextInt();sumR = new int[H];sumC = new int[W];arr = new int[H][W];for(int i = 0; i<H; i++) {for(int j = 0; j<W; j++) {arr[i][j] = sc.nextInt();sumR[i]+=arr[i][j];}}for(int j = 0; j<W; j++) {for(int i = 0; i<H; i++) {sumC[j] +=arr[i][j];}}}public int getMin(int[] a) {int min=0;for(int i=1; i<a.length; i++) {if(a[min]>a[i]) min = i;}return min;}public void solve() {for(int temp = 0; temp<K&&temp<(W+H); temp++) {int minSumR = getMin(sumR);int minSumC = getMin(sumC);if((W*X-sumR[minSumR])>=(H*X-sumC[minSumC])&&((W*X-sumR[minSumR])>0)) {for(int j = 0; j<W; j++) {sumC[j] = sumC[j]-arr[minSumR][j]+X;arr[minSumR][j] = X;}sumR[minSumR] = W*X;} else if((W*X-sumR[minSumR])<=(H*X-sumC[minSumC])&&((H*X-sumC[minSumC])>0)) {for(int i=0; i<H; i++ ){sumR[i] = sumR[i]-arr[i][minSumC]+X;arr[i][minSumC] = X;}sumC[minSumC] = H*X;}}int sum = 0;for(int i= 0; i<H; i++) {sum+=sumR[i];}for(int i = 0; i<H; i++) {for(int j = 0; j<W; j++) {System.out.print(arr[i][j]+" ");}System.out.println();}System.out.println(sum);}public static void main(String[] args) {Main m = new Main();m.solve();}}
跑出来,第一个例子不对。死活找不到原因。
大神给举例:
3
2
3
2
-100 -100
-1 -1
-1 -1
按照我的想法,跑出来是10
但是实际上可以有
3 3
3 3
3 3
输出是18。
修改后代码如下:
package Indeed;import java.util.ArrayList;import java.util.Collections;import java.util.List;import java.util.Scanner;public class Third {private int[] arr = {0,1,2,3,4,5,6,7,8,9};private int k;private int col;private int[][] nums;private int[] sumC;private int x;private int max;private int changeNums;public Third(int H, int W,int X,int changeNums,int[][] nums) {this.k = H;this.col = W;this.nums = nums;this.x = X;this.changeNums = changeNums;sumC = new int[col];for(int j = 0; j<col; j++) sumC[j] = 0;}public int solve() {int max = Integer.MIN_VALUE;for(int i = 0; i<(1<<k); i++) {int n=0;for (int j=0;j<k;j++)if(((i>>j)&1)==1)n++;int length =changeNums-n;if(length<0) continue;int[][] numsAfter = nums;for (int j=0;j<k;j++)if(((i>>j)&1)==1)for ( int l = 0 ; l < col ; l ++ )numsAfter[j][l] = x ;for(int j = 0; j<col;j++) {sumC[j] = 0;for(int t = 0; t<k; t++) {sumC[j]+=numsAfter[t][j];}}sort(sumC);for(int t = 0; t<col&&t<length&&sumC[t]<k*x;t++) {sumC[t] = k*x;}int result = 0;for(int t = 0; t<col; t++) {result+=sumC[t];}if(i==120) {for(int row = 0; row<k; row++) {for(int j = 0;j<col; j++) {System.out.print(numsAfter[row][j]+" ");}System.out.println();}System.out.println(result+" max:"+max);}max = Math.max(max, result);}return max;}public void sort(int[] a) {for(int i = 0; i<a.length; i++) {for(int j = i; j<a.length; j++) {if(a[i]>a[j]) {int temp = a[j];a[j] = a[i];a[i] = temp;}}}}public static void main(String[] args) {Scanner sc = new Scanner(System.in);int H = sc.nextInt();int W = sc.nextInt();int x = sc.nextInt();int k = sc.nextInt();int[][] nums = new int[H][W];for(int i = 0; i<H; i++) {for(int j = 0; j<W; j++) {nums[i][j] = sc.nextInt();}}Third th = new Third(H,W,x,k,nums);System.out.println(th.solve());}}
嗯。还是错了。大神帮忙找原因。
原因找到。
主要有两个原因。
1、int[] a = new int[2][3];
int[] b = a;
b[1] =2;
a的大小也会随着b的大小的改变而改变,
因此 代码里的 numsAfter = nums 应该改成每一个数字进行赋值。
2、sort排序。
sort是对整个sumC数组进行的排序。但是实际上 sumC数组里面只有前col个有数据,剩余部分的数据都是之前的数据未清除。所以应是对前col个数据进行排序。然后同样只计算前col个数据的和。
修改后的代码如下:
package Indeed;import java.util.ArrayList;import java.util.Collections;import java.util.List;import java.util.Scanner;public class Third {private int[] arr = {0,1,2,3,4,5,6,7,8,9};private int k;private int col;private static int[][] nums = new int[10][200];private int[] sumC = new int[200];private int x;private int max;private int changeNums;public Third() {Scanner sc = new Scanner(System.in);k = sc.nextInt();col = sc.nextInt();x = sc.nextInt();changeNums = sc.nextInt();for(int i = 0; i<k; i++) {for(int j = 0; j<col; j++) {nums[i][j] = sc.nextInt();}}}public int solve() {int max = Integer.MIN_VALUE;for(int i = 0; i<(1<<k); i++) {int n=0;for (int j=0;j<k;j++)if(((i>>j)&1)==1)n++;int length =changeNums-n;if(length<0) continue;int[][] numsAfter = new int[k][col];for(int l = 0; l<k; l++) {for(int t = 0; t<col; t++) {numsAfter[l][t] = nums[l][t];}}for (int j=0;j<k;j++)if(((i>>j)&1)==1)for ( int l = 0 ; l < col ; l ++ )numsAfter[j][l] = x ;for(int j = 0; j<col;j++) {sumC[j] = 0;for(int t = 0; t<k; t++) {sumC[j]+=numsAfter[t][j];}}sort(sumC,0,col);for(int t = 0; t<col&&t<length&&sumC[t]<k*x;t++) {sumC[t] = k*x;}int result = 0;for(int t = 0; t<col; t++) {result+=sumC[t];}max = Math.max(max, result);}return max;}public void sort(int[] a,int start, int end) {for(int i = start; i<end; i++) {for(int j = i; j<end; j++) {if(a[i]>a[j]) {int temp = a[j];a[j] = a[i];a[i] = temp;}}}}public static void main(String[] args) {Third th = new Third();System.out.println(th.solve());}}
整理了下代码:
package Indeed;/* * 882914-89 -76 92 61 5 -18 -68 90-3 44 -9 84 -36 51 -43 8511 -72 5 -90 -43 -94 5 97-90 22 66 29 -26 66 -29 -3882 -60 60 -9 -23 -8 -59 -13-4 -68 -4 59 78 25 99 -86-4 23 21 53 53 -25 -31 -6638 50 -35 -98 -49 -33 -31 88output:21003232-100 -100-1 -1-1 -1output:18 */import java.util.Scanner;public class Main {private int H;private int W;private int X;private int K;private int[][] arr = new int[10][200];private int[][] arrAfter = new int[10][200];public Main() {Scanner sc = new Scanner(System.in);H = sc.nextInt();W = sc.nextInt();X = sc.nextInt();K = sc.nextInt();arr = new int[H][W];for(int i = 0; i<H; i++) {for(int j = 0; j<W; j++) {arr[i][j] = sc.nextInt();}}}public int solve() {int max = Integer.MIN_VALUE;for(int s = 0; s<(1<<H);s++) {int n = 0;int[][] nums = new int[H][W];for(int i = 0; i<H; i++) {for(int j = 0; j<W; j++) {nums[i][j] = arr[i][j];}}for(int j = 0; j<H; j++) {if(((s>>j)&1)==1) {for(int l = 0; l<W; l++) {nums[j][l] = X;}n++;}}int size = K-n;int[] colSum = new int [W];for(int j = 0; j<W; j++) {colSum[j] = 0;for(int i = 0; i<H; i++) {colSum[j]+=nums[i][j];}}sort(colSum,0,W);for(int i = 0; i<size&&i<W&&colSum[i]<H*X; i++) {colSum[i]=H*X;}int result = 0;for(int i = 0; i<W; i++) {result+=colSum[i];}max = Math.max(result, max);}return max;}public void sort(int[] colSum, int start, int end) {for(int i = start; i<end; i++) {for(int j = i; j<end; j++) {if(colSum[i]>colSum[j]) {int temp = colSum[i];colSum[i] = colSum[j];colSum[j] = temp;}}}}public static void main(String[] args) {Main m = new Main();System.out.println(m.solve());}}
- Indeed修改数组行或者列,得到最大数组和
- 求数组的最大子列和
- 得到数组中的最大,最小值
- 得到二位数组的行数和列数
- 【滴滴笔试】得到数组的最大子序列和
- 连续子数组的最大和:DP或者贪心
- 动态分配数组内存赋值后,怎样得到数组的行数和列数
- 每日一道算法题3——得到数组子数组最大和
- 数组鞍点:行最大,列最小,只有一个
- php实现 数组行里最大 列里最小
- 子数组和最大
- 最大子数组和
- 最大子数组和
- 子数组最大和
- 数组最大和
- 最大子数组和
- 一维子数组最大和
- 子数组最大和
- Android 中的 Service 全面总结
- GCD - 2
- Mac 安装nginx
- Maven打包跳过测试类
- MyBatis(二)--对MySQL数据表进行CRUD操作
- Indeed修改数组行或者列,得到最大数组和
- mysql报错
- 档案与文件系统压缩与打包
- jQuery源码分析之ajaxTransport
- SpringMVC对异常处理的支持
- 经常用到的Sublime2插件
- leetcode-Lowest Common Ancestor of a Binary Tree
- 关于Azure HDInsight资源调用的问题及解决办法
- more than 255 characters in filepath