格格取数
时间限制:2000ms
单点时限:1000ms
内存限制:256MB
描述
给你一个m x n (1 <= m, n <= 100)的矩阵A (0<=aij<=10000),要求在矩阵中选择一些数,要求每一行,每一列都至少选到了一个数,使得选出的数的和尽量的小。
输入
多组测试数据。首先是数据组数T
对于每组测试数据,第1行是两个正整数m, n,分别表示矩阵的行数和列数。
接下来的m行,每行n个整数,之间用一个空格分隔,表示矩阵A的元素。
输出
每组数据输出一行,表示选出的数的和的最小值。
数据范围
小数据:1 <= m, n <= 5
大数据:1 <= m, n <= 100
- 样例输入
-
2 3 3 1 2 3 3 1 2 2 3 1 5 5 1 2 3 4 5 5 1 2 3 4 4 5 1 2 3 3 4 5 1 2 2 3 4 5 1
- 样例输出
-
Case 1: 3 Case 2: 5
代码:1 import java.util.Scanner; 2 3 4 public class Main { 5 6 public static void main(String[] argv){ 7 Scanner in = new Scanner(System.in); 8 Main Index = new Main(); 9 //获取Case数量 10 int Num = Integer.parseInt(in.nextLine()); 11 //建立存储结果的数组 12 int [] result = new int [Num]; 13 for(int p=0; p<Num; p++){ 14 //循环处理Case 15 //获取行数和列数 16 String xy[] = in.nextLine().split(" "); 17 int x = Integer.parseInt(xy[0]); 18 int y = Integer.parseInt(xy[1]); 19 //存储数据的表格 20 int[][] k = new int[x][y]; 21 for(int i=0; i<x; i++){ 22 String temp[]=in.nextLine().split(" "); 23 for(int j=0; j<y; j++){ 24 k[i][j]=Integer.parseInt(temp[j]); 25 } 26 } 27 //获取最小值 28 result[p] = Index.Have(k); 29 } 30 in.close(); 31 //输出结果 32 for(int i = 0 ; i < Num; i++){ 33 System.out.println("Case "+i+": "+result[i]); 34 } 35 36 } 37 public int Have(int[][]k){ 38 39 int [][] key = k; 40 int leng = key.length; 41 int sum=0; 42 int [] g = new int [leng]; 43 //动态规划求值 44 for(int i=0; i<leng; i++){ 45 int min = sum + key[i][i]; 46 int t = i; g[i]=i; 47 for(int j=0;j<i;j++){ 48 if(sum+key[j][i]+key[i][g[j]]-key[j][g[j]]<min){ 49 min = sum+key[j][i]+key[i][g[j]]-key[j][g[j]]; 50 t=j; 51 } 52 } 53 //获取交换值并处理 54 if(t<i){ 55 g[i]=g[t];g[t]=i; 56 } 57 //重新定义前i行i列最小值 58 sum = min; 59 } 60 return sum; 61 } 62 }
测试结果: