This is the 2015 last multi-school DP problem, at that time only blame their foundation is too poor, think for 1 hours to think out, hey, September to consolidate the foundation for regional races to prepare. Topic Portal
The title means give you n yuan, M candy, each kind of candy have p, a, B, p for unit price, assuming pay w*p yuan, then he can get A*w + b candy. Find the maximum number of candies.
At that time saw this question, think is a complete backpack, set DP[I][J] said to buy the first item I have spent J Yuan, get the most candy number.
It is easy to think of the transfer equation as:
DP[I][J] = max (Dp[i-1][j], dp[i-1][j-k * p] + A * k + b);(k > 0 && k * P <= J)
When the confidence is ready to knock suddenly found that the time complexity of O (n^3), and N maximum of 1000, no doubt will time out. What to do?
Then we think we use the 01 knapsack thinking to think about this problem, we can optimize it to O (n^2), and then suddenly found a problem, because more than a B, found to consider whether the first time to buy, then we open a vis array to indicate that there is no buy, 1 said to buy, 0 said no.
Enclose the total code:
1#include <cstdio>2#include <cstring>3#include <algorithm>4 using namespacestd;5 6 Const intN = -+5;7 8 intT, N, M;9 Ten intP[n], a[n], b[n]; One A intVis[n][n], dp[n][n]; - - voidWork () { theMemset (DP,0,sizeof(DP)); -memset (Vis,0,sizeof(Vis)); - for(inti =1; I <= N; i + +){ - for(intj =0; J <= M; J + +){ +DP[I][J] = dp[i-1][j]; - if(J >=P[i]) { + intt = Dp[i][j-p[i]] +A[i]; A if(!vis[i][j-p[i]) T + =B[i]; at intT1 = dp[i-1][j-p[i]] + a[i] +B[i]; - if(T1 > t) t =T1; - if(T >Dp[i][j]) { -DP[I][J] =T; -VIS[I][J] =1; - } in } - } to } +printf"%d\n", Dp[n][m]); - } the * intMain () { $scanf"%d", &T);Panax Notoginseng while(t--){ -scanf"%d%d", &m, &n); the for(inti =1; I <= N; i + +) scanf ("%d%d%d", p + I, A + I, B +i); + Work (); A } the return 0; +}
View Code
Complete Backpack Variant (hdu5410)