Http://acm.zju.edu.cn/onlinejudge/showProblem.do? Problemcode = 2972.
I is the current segment, and J is the remaining physical strength after I. There are three running methods available in section I:
The first method consumes F1 physical strength, so ensure that J + F1 <= m. DP [I] [J] = min (DP [I] [J], DP [I-1] [J + F1] + T1 );
The second method does not consume physical strength. DP [I] [J] = min (DP [I] [J], DP [I-1] [J] + T2 );
The third increase F2 physical strength, ensure that the j-f2> = 0. DP [I] [J] = min (DP [I] [J], DP [I-1] [j-f2] + T3 );
Another case needs to be considered separately, that is, to run in the third way, so that the accumulation of physical strength is greater than m, take m as the standard. So its previous state is not DP [I-1] [j-f2], it should be DP [I-1] [s-1... m-f2]. Therefore, we need to add a loop to separate the minimum values in this case.
Code:
# Include <cstdio>
Const int max = 1E + 9;
Int DP [120] [120];
Int min (int A, int B ){
Return A> B? B:;
}
Int main (){
Int T, I, j, n, m, T1, T2, T3, F1, F2;
Scanf ("% d", & T );
While (t --){
Scanf ("% d", & N, & M );
For (I = 0; I <= N; I ++)
For (j = 0; j <= m; j ++)
DP [I] [J] = max;
DP [0] [m] = 0;
For (I = 1; I <= N; I ++ ){
Scanf ("% d", & T1, & T2, & T3, & F1, & F2 );
For (j = 0; j <= m; j ++ ){
If (J + F1 <= m)
DP [I] [J] = min (DP [I] [J], DP [I-1] [J + F1] + T1 );
DP [I] [J] = min (DP [I] [J], DP [I-1] [J] + T2 );
If (j-f2> = 0)
DP [I] [J] = min (DP [I] [J], DP [I-1] [j-f2] + T3 );
}
For (j = 1; j <= F2; j ++) // separately
If (m-j> = 0)
DP [I] [m] = min (DP [I] [m], DP [I-1] [M-J] + T3 );
}
Int x = max;
For (j = 0; j <= m; j ++)
If (DP [N] [J] <X) x = DP [N] [J];
Printf ("% d \ n", X );
}
Return 0 ;}