Pick apples Time limit:1000ms Memory limit:165536k Title Description
Once ago, there is a mystery yard which only produces three kinds of apples. The number of each kind is infinite. A girl carrying a big bag comes into the yard. She was so surprised because she had never seen so many apples before. Each kind of apple have a size and a price to be sold. Now the little girl wants to gain more profits, but she does isn't know how. So she asks to help, and tell she the most profits she can gain.
Input
The first line there are an integer t (t <=), indicates the number of test cases.
In each case, there is four lines. In the first three lines, there is both integers S and P in each line, which indicates the size (1 <= s<=) and T He price (1 <= P <= 10000) of this kind of apple.
The fourth line there are an integer V, (1 <= V <= 100,000,000) indicates the volume of the girl ' s bag.
Output
For each case, first output of the case number then follow the most profits she can gain.
Sample input
1 1
1 6
Sample output
Case 1:6
Hint Source 2012 "Wave Cup" the third ACM University Student Program Design competition in Shandong Province
Problem Solving Ideas:
From yesterday after the game began to work out the problem, when the first feeling is to complete the backpack, but the amount of data is too large, the direct full backpack will definitely time out. After the game to see the problem-solving report only to know that the topic with a wide range of greed, a small range of full backpack, this good understand, see the online code for the small range of AC is 1000, but this is the teacher today proved to be wrong, the background test data is not perfect, such as the teacher gave this group of test data:
98 99
99 100
100 101
2000 This set of test data with a small range of 1000 code test results of 2000, but the correct answer should be 2020, although the first is the best thing, but here we have to choose the third 100 101 is the correct answer. So the small range of 1000 is wrong, the small area here should be three kinds of goods capacity of the least common multiple, that is 100*100*100, with 1000000 on it can be. Do this spent maths really a lot of kung fu, the whole morning is almost in the runtime error and wrong answer spent. Looking for a mistake for a long time. Note that the limited capacity V to use a long long type, dp[] array also to use a long long type. Dp[] Array can not only open 1 million, to be as large as possible, because in the greedy part only select the best kind of goods, but more than 1000000 of that part does not necessarily divisible the capacity of the item, that is, may be the remaining portion of the capacity added to 1000000 together with a complete backpack to do. This is the reason why countless times runtime error. Later saw a solution, particularly ingenious, no use of greed and backpack, is enumerated in addition to the best items of the two outside the two backpack choice number, here is a limited condition, that is not the best items are selected number of items must be smaller than the capacity of the best items,
such as this set of test data;
Best Item 3 6
Other 2 3 Choose a 2 3 Choose two X 4 6 select Three 6 9 but when we select 2 best items It is 6 12, which is obviously better than selecting three other items, which means that there are 0, 1, 2 in the number of other items that may be selected. These are possible, the size of the backpack is less than 100, so two-tier loop enumeration of the other two items are selected, the maximum value in the calculation can be, the complexity of 0 (100*100).
First method (sort of greedy + complete backpack):
#include <iostream> #include <string.h> #include <algorithm>using namespace Std;const int lcm=1000000 ;//Three kinds of size of least common multiple long long DP[LCM*2+2],V;//DP array to open large enough, can not only open the LCM, the reason for the comment, and V to use a long longstruct n{int s,p; Double pri;} Node[3];bool CMP (n A, n b) {return a.pri<b.pri;} Long Long maxll (long long A,long long b) {return a>b?a:b;} void Compack ()//Full backpack {memset (dp,0,sizeof (DP)); for (int i=0;i<3;i++) for (int j=node[i].s;j<=v;j++) DP[J]=MAXLL (DP[J],DP[J-NODE[I].S]+NODE[I].P);} int main () {int t;cin>>t;int c=1; while (t--) {for (int i=0;i<3;i++) {cin>>node[i].s>>node[i].p; NODE[I].PRI=NODE[I].S*1.0/NODE[I].P; } cin>>v; if (V<=LCM)//small range Direct full backpack {compack (); cout<< "Case" <<c++<< ":" <<dp[V]<<endl; } else {sort (node,node+3,cmp);//Sort, optimal in the first v-=lcm;//beyond 100Part of 0000 long long ans=0; ans=ans+ (V/NODE[0].S*NODE[0].P);//The greedy part chooses the first obtained value v=lcm+ (V-V/NODE[0].S*NODE[0].S);//This explains why the DP must be open enough to open only the LCM, because For the greedy part may not be divisible, there is the remainder of the compack ();//Full Backpack cout<< "case" <<c++<< ":" <<ans+dp[V]< <endl; }} return 0;}
Second method (unsorted greedy + full backpack):
#include <iostream> #include <string.h>using namespace Std;const int Lcm=1000000;long long dp[lcm*2+2],v; int s[5],p[5];void Compack () {memset (dp,0,sizeof (DP)); for (int i=0;i<3;i++) for (int j=s[i];j<=v;j++) {if (Dp[j]<dp[j-s[i]]+p[i]) dp[j]=dp[j- S[i]]+p[i]; }}int Main () {int t;cin>>t;int c=1; while (t--) {double pr,temp=0; int id; for (int i=0;i<3;i++) {cin>>s[i]>>p[i]; Pr=1.0*p[i]/s[i]; if (TEMP<PR) {temp=pr; Id=i; }} cin>>v; if (V<=LCM) {compack (); cout<< "Case" <<c++<< ":" <<dp[V]<<endl; } else {Long long ans= (V-LCM)/s[id]*p[id]; v=v-(V-LCM)/s[id]*s[id]; Compack (); cout<< "Case" <<c++<< ":" <<ans+dp[v]<<endl } }}
Third method (enum not sorted):
#include <iostream> #include <stdio.h>using namespace Std;int s[4],p[4];long long Llmax (Long long A,long long b) {return a>b?a:b;} int main () {int t; cin>>t; int c=1; while (t--) {for (int i=1; i<=3; i++) cin>>s[i]>>p[i]; int V; cin>>v; int k1=1,k2,k3; for (int i=2; i<=3; i++) {if (p[i]*s[k1]>p[k1]*s[i])//Judgment priority k1=i; } if (k1==1) {k2=2;k3=3;};/ /K1 is the best item, K2,K3 is who has no relationship if (k1==2) {k2=1,k3=3;}; if (k1==3) {k2=1,k3=2;}; Long Long ans=0; for (int i=0; i<s[k1]; i++)//enumeration {for (int j=0; j<s[k1]; J + +) {Long long TEMP=I*S[K2]+J*S[K3]; if (temp>v) break; else {long long v=v-temp; Ans=llmax (Ans,v/s[k1]*p[k1]+i*p[k2]+j*p[k3]);//Select Maximum}}} cout<< "Case" <<c++<< ":" <<ans<<endl; } return 0;}
Fourth method (sort enumeration):
#include <iostream> #include <stdio.h> #include <algorithm>using namespace std;struct n{int s,p; Double pri;} Node[4];bool CMP (N a,n b) {if (A.PRI<B.PRI) return true; return false;} Long Long Llmax (long long A,long long b) {return a>b?a:b;} int main () {int t; cin>>t; int c=1; while (t--) {for (int i=0; i<3; i++) {cin>>node[i].s>>node[i].p; node[i].pri=1.0*node[i].s/(1.0*NODE[I].P); } int V; cin>>v; Sort (node,node+3,cmp); Long Long ans=0; for (int i=0, i<node[0].s; i++) {for (int j=0; j<node[0].s; J + +) {long L Ong Temp=i*node[1].s+j*node[2].s; if (temp>v) break; else {long long v=v-temp; Ans=llmax (ANS,V/NODE[0].S*NODE[0].P+I*NODE[1].P+J*NODE[2].P); } }} cout<< "Case" <<c++<< ":" <<ans<<endl; } return 0;}
[2012 Shandong ACM Provincial Race] Pick apples (greedy, full backpack, enumeration)