编程之美2015测试赛之格格取数

格格取数

时间限制: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 }

测试结果:

原文地址:https://www.cnblogs.com/udld/p/4417427.html