Indeed修改数组行或者列,得到最大数组和

输入

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;
/*
 * 
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
2
3
2
-100 -100
-1   -1
-1   -1
output: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());
	}

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值