Description
Give you A matrix A (0 <= aij <= 100) of m x n (1 <= m, n <= 10000). You must select A number in the matrix, each row and column must have at least one number, so that the sum of the selected numbers is as small as possible.
Input
Multiple groups of test data. The first is the number of data groups T
For each group of test data, the first row is two positive integers m, n, indicating the number of rows and columns of the matrix respectively.
In the next m row, n integers are separated by A space to represent the elements of matrix.
Output
Output a row of data in each group, indicating the minimum value of the sum of the selected numbers.
Data range
Small Data: 1 <= m, n <= 5
Big Data: 1 <= m, n <= 100
Ideas:Assume M = N first, and M is required if the brute force is searched! Times, when M = 100, it doesn't work at all.
Greedy Algorithm? First, find the smallest one, and then find the smallest one. If the rows or columns are repeated, skip to continue searching. This method is extremely complex, but it cannot prove that greedy is wrong.
For example:
0 1 4
1 5 8
3 2 4
If the greedy algorithm is used, the answer is 0 + 2 + 8 = 10, but the answer is obviously 1 + 1 + 4 = 6.
Some people used greedy algorithms to submit the result as AC, which indicates that Microsoft's test data is faulty.
Let's talk about my ideas. Let's evaluate whether they are correct:
I use dynamic programming. dp [k] [I] [j] indicates the minimum value of the matrix with the horizontal I and vertical j k * k size. In this way, from 1 to M, I and j are inner loops, and the range is the number of k * k matrices in the M * N matrix. The following is a simple example. M = N = 3.
When k = 1, dp [I] [I] [j] Is each element of the matrix.
When k = 2, the range of I and j is 2*2. Evaluate dp [2] [1] [1] First, that is, the value of the rectangle 2*2 in the upper left corner, it is the addition of diagonal elements, taking the minimum value, and the remaining four 2*2 rectangular values are similar to the calculation, so k = 2 is all calculated.
When k = 3, I and j can only be 1. The minimum value is (2*2 rectangle in the upper left corner + matrix value in the lower right corner) (in the upper right corner + lower left corner )... The minimum value of the four values.
If k continues to increase, take the minimum values of four values for each I, j, and k increments one by one.
The Code is as follows:
//source here#include<iostream>#include <memory.h>using namespace std;int T,M,N,a[100][100],i,j,k,p;int dp[100][100][100];int main(){ cin>>T; for( p=0;p<T;p++) {cin>>M>>N;memset(dp,0,sizeof(dp));for(j=0;j<M;j++)for(k=0;k<N;k++) cin>>a[j][k]; for(j=0;j<M;j++)for(k=0;k<N;k++) dp[1][j+1][k+1]=a[j][k]; for (k=2;k<=N;k++)for(i=1;i<=M-k+1;i++)for(j=1;j<=N-k+1;j++)dp[k][i][j]=min(min(dp[k-1][i][j]+a[i+k-2][j+k-2],dp[k-1][i+1][j]+a[i-1][j+k-2]),min(dp[k-1][i][j+1]+a[i+k-2][j-1],dp[k-1][i+1][j+1]+a[i-1][j-1])); cout<<"Case "<<p+1<<":"<<dp[N][1][1]<<endl; } return 0;}
Many of the data I tested on VC is correct, but the submission is WA, so I am not sure whether this idea is correct. Please comment on it.
The complexity is about 4*(1 ^ 2 + 2 ^ 2 +... + M ^ 2), O (M ^ 3), and acceptable.
Of course, the question did not say M = N, when the two are not equal, M> N, first calculate the number of N * N, there is a M-N + 1, the remaining M-N line to take the minimum value of each line, add the first M-N + 1 minimum and the minimum value of the remaining rows, and finally take the minimum value of the M-N + 1 count.
Correction: This idea is still incorrect. As I mentioned in the following comments, it is a bit complicated to use the Hungary method...