Uva_000017
I had no clue at the beginning. Later, a buddy in the dormitory asked me what the problem was. After I explained it, I suddenly found that this problem could also be solved using a backpack.
Because every candidate teacher is either required or not, this is a feature of the 0-1 backpack. The question is, can we find a physical state.
In reality, we can regard each course as the size of a 0-1 backpack problem, set f [I] [J] to the minimum cost when the I-th instructor's course status is J, then f [I] [J] = min {f [I-1] [J], F [I-1] [k] + W [I]}, the K State is obtained by the J state and the I-th teacher can teach the course. If a certain item is greater than 2, it is treated as 2, it means that this teacher can skip this course.
When initializing the boundary, You can initialize f [0] [J] to the total money spent by teachers who must be hired, among them, the status of each course in status J is not less than the status of all hired teachers. For example, there are three courses in total, and the status and status of all necessary teachers are 2 1 1. That is to say, one teacher is missing for each of the two courses, and two teachers are missing for one course, then, we initialize 2 1, 2 2 1, 2 1 2, 2 2 2, and 2 2 to the starting cost. This means that some teachers must be hired, let new teachers teach.
Of course states must be compressed into an integer During calculation.
# Include <stdio. h>
# Include < String . H>
# Include <ctype. h>
# Define Maxd 10000
# Define Maxn 110
# Define INF 1000000000
Int S, M, N, P, F [maxn] [maxd], W [maxd], t [maxd] [ 10 ], [ 10 ], P [ 10 ];
Char B [ 100 ];
Int Init ()
{
Int I, J, K;
Gets (B );
Sscanf (B, " % D " , & S, & M, & N );
If (! S)
Return 0 ;
Return 1 ;
}
Void Solve ()
{
Int I, J, K, V, res, temp, OK;
V = 0 ;
For (I = 1 ; I <= s; I ++)
A [I] = 2 ;
For (I = 0 ; I <m; I ++)
{
Gets (B );
K = strlen (B );
Sscanf (B, " % D " , & Temp );
V + = temp;
For (J = 0 ; Isdigit (B [J]); j ++ );
For (++ J; j <K; j ++)
{
Sscanf (& B [J], " % D " , & Temp );
If (A [temp])
A [temp] --;
While (Isdigit (B [J])
J ++;
}
}
Memset (t, 0 , Sizeof (T ));
For (I = 1 ; I <= N; I ++)
{
Gets (B );
K = strlen (B );
Sscanf (B, " % D " , & Temp );
W [I] = temp;
For (J = 0 ; Isdigit (B [J]); j ++ );
For (++ J; j <K; j ++)
{
Sscanf (& B [J], " % D " , & Temp );
T [I] [temp] = 1 ;
While (Isdigit (B [J])
J ++;
}
}
Memset (F, 0x3f , Sizeof (F ));
For (I = 1 , P = 0 ; I <= s; I ++)
P = 3 * P + 2 ;
For (I = 0 ; I <= P; I ++)
{
Temp = I;
For (J = 1 ; J <= s; j ++)
{
P [J] = TEMP % 3 ;
Temp/= 3 ;
}
OK = 1 ;
For (J = 1 ; J <= S & P [J]> = A [J]; j ++ );
If (J = S +1 )
F [ 0 ] [I] = V;
}
For (I = 1 ; I <= N; I ++)
For (J = 0 ; J <= P; j ++)
{
F [I] [J] = f [I- 1 ] [J];
Temp = J;
For (K = 1 ; K <= s; k ++)
{
P [k] = TEMP % 3 ;
Temp/= 3 ;
}
For (K = 1 ; K <= s; k ++)
If (T [I] [k] & P [k] < 2 )
P [k] ++;
Temp = 0 ;
For (K = s; k> =1 ; K --)
Temp = 3 * Temp + P [k];
If (F [I- 1 ] [Temp] + W [I] <F [I] [J])
F [I] [J] = f [I- 1 ] [Temp] + W [I];
}
Printf ( " % D \ n " , F [N] [ 0 ]);
}
Int Main ()
{
While (Init ())
Solve ();
Return 0 ;
}