There are n person and N job to do. the I-th person do J-th job will cost different certain money. Choose a scheme that every person only do one different job, and total
Cost is minimum.
Input
Input consists of several test cases. the first line of each case is a positive interger N (2 <= n <14), it is the number of persons (and jobs ). the next N line include N integers,
The cost of I-th person doing J-th job is the J-th element in line I.
Output
For each input N, You Should the minimum cost in one line.
Sample Input
310 93 7312 69 4088 62 76
Sample output
112
Status compression DP. Because N is relatively small, it is easy to think of State compression DP.
Use a binary mechanism to indicate the assignment status of a job. n = 5 is used as an example.
For example, 01011 indicates 1-5 jobs, unallocated, allocated, unallocated, allocated, and allocated
If you allocate work to 01011 people based on the status of 4th, the new status can be 11011, 01111, and the solution of these statuses needs to be updated.
In turn, we want to find the optimal solution of State 01111, so we only need to find the optimal solution from the subproblem, and do not need to care about how the subproblem's optimal solution is achieved.
For example, the status (subproblem) related to status 01111 is as follows:
01110 (in the case of 2, 3, and 4 jobs that have been assigned, 4th People can select 5th jobs to reach the status of 01111)
01101 (in the case of 2, 3, and 5 jobs that have been assigned, 4th People can select 4th jobs to reach the status of 01111)
01011 (in the case of 2, 4, and 5 jobs that have been assigned, 4th People can select 3rd jobs to reach the status of 01111)
00111 (in the case of 3, 4, and 5 jobs allocated, 4th People can select 2nd jobs to reach the status of 01111)
# Include <stdio. h> # include <memory. h> # include <limits. h> int M [14] [1 <14]; // M [I] [J] indicates that work has been assigned to the former I, the job allocation status is the optimal bool flag in the binary representation of J [14] [1 <14]; // flag [I] [J] indicates whether the status is reachable or valid. int A [14] [14]; // stores the input int main () {int N, I, j, k; while (scanf ("% d", & N )! = EOF) {memset (flag, false, sizeof (FLAG); int max = 1 <n; // The maximum state is max-1, that is, N-bit all is 1, use Max to indicate the upper limit of the status for (I = 1; I <= N; I ++) for (j = 1; j <= N; j ++) scanf ("% d", & A [I] [J]); for (I = 1; I <= N; I ++) for (j = 0; j <Max; j ++) m [I] [J] = int_max; m [0] [0] = 0; flag [0] [0] = true; for (I = 1; I <= N; I ++) for (j = 0; j <Max; j ++) // handle all reachable states of the previous I-1 personal assigned work {If (! Flag [I-1] [J]) continue; // If (I-1, j) is not valid, skip for (k = 1; k <= N; k ++) // assignment of jobs that can be allocated to individuals I {int mask = 1 <(k-1); If (J & Mask) continue; // work allocated to the nth K, skip if (M [I-1] [J] + A [I] [k] <m [I] [j | mask]) // allocate the k-th job to the I-th individual, update the resolution of the reached state at the same time {M [I] [j | mask] = m [I-1] [J] + A [I] [k]; flag [I] [j | mask] = true ;}} printf ("% d \ n", M [N] [(1 <n) -1]);} return 0 ;}