Ultraviolet A 10465 Homer Simpson (complete backpack: Two-Dimensional Target condition), 10465 homer
Ultraviolet A 10465 Homer Simpson (complete backpack: Two-Dimensional Target condition)
Http://uva.onlinejudge.org/index.php? Option = com_onlinejudge & Itemid = 8 & page = show_problem & problem = 1406
Question:
There are two kinds of hamburgers (the number of hamburgers is unlimited). It takes n minutes to eat one, and m minutes to eat the other. now you have a t minute to ask if you have to waste at least a few minutes and cannot eat a hamburger (you can either finish a whole hamburger or stop eating it ). when it takes the most time to eat a hamburger, how many hamburgers can you eat at most?
Analysis:
This questionRestrictionsYes: Total time <= t minutes.
This questionTarget ConditionYes: the total time is as large as possible. If the time is the same, the more hamburgers, the better.
Two-dimensional (or even multi-dimensional) Target conditions can be implemented in two ways.
The first method is:Use a full backpack to find the maximum time tmax, and then use a full backpack to find out that the time for eating a hamburger is exactly the same as that of the maximum time tmax. You can eat a maximum of several hamburgers.
First, use the full backpack to find the maximum time tmax. with dp [I] [j] = x, it indicates that the total time of a hamburger cannot exceed j minutes after the decision is completed. the following recursive formula is provided:
Dp [I] [j] = max (dp [I-1] [j], dp [I] [j-time [I] + time [I])
The former indicates that no I hamburger is selected, and the latter indicates that at least one I hamburger is selected.
Initialize to dp all 0. Final tmax = dp [n] [t].
Then we calculate the maximum number of hamburgers in the case that the time is exactly tmax. when dp [I] [j] = x indicates that the maximum number of hamburgers is x when the total number of items is determined and the time is exactly j minutes. the following recursive formula is provided:
Dp [I] [j] = max (dp [I-1] [j], dp [I] [j-time [I] + 1)
The former indicates that no I hamburger is selected, and the latter indicates that at least one I hamburger is selected.
Initialize to dp full-1. and dp [0] [0] = 0.
Final maximum hamburger COUNT = dp [n] [tmax].
The second method is:
UVA12563 has the same idea:
Http://blog.csdn.net/u013480600/article/details/40376143
In general, the question about our backpack is to ask you <= t time, how to choose which hamburgers (without exceeding the total time) can make the longest time to eat or the most to eat. however, we need to consider two optimal conditions at the same time. What should we do?
We set dp [I] [j] = x to indicate the time it takes to eat a hamburger when the decision is complete after I have selected an item (or not selected) <= j, the obtained optimal state is x. (Here, x is not the longest time or the maximum number of songs we call at ordinary times)
How can we understand the fact that the optimal state is x?Assume that there are two ways to select the first I hamburger so that the total duration of the first I item after decision-making is x1 and x2.
Therefore, if the time for taking a hamburger in the x1 state is greater than the time for taking a hamburger in the x2 state, the x1 state is obviously better. Therefore, dp [I] [j] should be = x1.
If the time for eating a hamburger in the x1 state is equal to that in the x2 stateHamburger count> The number of hamburgers in the x1 status. Therefore, the x2 status is better. Therefore, dp [I] [j] Should = x2.
After the above analysis, we can use a structure (having two attributes of the time and number of hamburgers) to represent a State. The following state transfer formula can be obtained:
Dp [I] [j] = optimal (dp [I-1] [j],Based on dp [I-1] [j-time [I], select the new State tmp after the I-Hamburg)
Initialize all dp to 0. In the end, we ask for dp [n] [t].
The program uses a rolling array, so dp only has the [j] dimension.
AC code 1: done using method 1 two DP
# Include <cstdio> # include <cstring> # include <algorithm> using namespace std; const int maxn = 10000 + 5; int n, m, t; // meaning of the question int time [5]; // The time taken to eat the I-type hamburger int dp [maxn]; int main () {while (scanf ("% d", & time [1], & time [2], & t) = 3) {// maximum recurrence time memset (dp, 0, sizeof (dp); for (int I = 1; I <= 2; I ++) {for (int j = time [I]; j <= t; j ++) dp [j] = max (dp [j], dp [j-time [I] + time [I]);} int tmax = dp [t]; // Recursive Maximum hamburger count memset (dp,-1, sizeof (dp); dp [0] = 0; for (int I = 1; I <= 2; I ++) {for (int j = time [I]; j <= tmax; j ++) if (dp [j-time [I]! =-1) dp [j] = max (dp [j], dp [j-time [I] + 1 );} // output result printf ("% d", dp [tmax]); if (t> tmax) printf ("% d", t-tmax ); printf ("\ n");} return 0 ;}
AC code 2: method 2, once done by DP
# Include <cstdio> # include <cstring> # include <algorithm> using namespace std; const int maxn = 10000 + 5; int n, m, t; // meaning of the question int time [5]; // The time taken to eat the I-th hamburger struct Node // each State {int time; // The time taken to eat the hamburger int num; // Number of bool operator (const Node & rhs) const {return time <rhs. time | (time = rhs. time & num <rhs. num) ;}} dp [maxn]; int main () {while (scanf ("% d", & time [1], & time [2], & t) = 3) {// initialize memset (dp, 0, sizeof (dp); // recursive for (int I = 1; I <= 2; I ++) {for (int j = time [I]; j <= t; j ++) {Node tmp = dp [j-time [I]; tmp. time + = time [I]; tmp. num ++; if (dp [j] <tmp) dp [j] = tmp ;}/// output result printf ("% d", dp [t]. num); if (dp [t]. time <t) printf ("% d", t-dp [t]. time); printf ("\ n");} return 0 ;}