Given the empty and full weight of the savings tank, there are n kinds of coins, coins have value and weight, give the value of various coins p[i] and the corresponding weight w[i], the minimum value of the coin in the savings tank, if there is no way to put coins in line with the requirements, output "This is impossible".
Ideas:
Equivalent to a complete backpack for the minimum value, n in the coin corresponding to n objects, the object can be taken unlimited times, the storage tank of the coin weight (can be reduced empty tank) equivalent to the volume of the Backpack V.
Law One:
Directly extend the equation of 01 knapsack, use dp[i,v] to indicate the minimum value of the first I type of coin, the maximum storage tank weight is v. The equation of state transition is: Dp[i,v]=min (Dp[i-1,v-k*w[i]] + k*p[i]), 0<=k<= V/w[i], take the coins of the first I take K.
Recursion requires n*v state, each state takes time to O (V/weight[i]), total time complexity is O (nv*σ (v/c[i)), Space complexity O (n2)
Recursive type:
for (int i=1; i<=n; + +i ) for (int v=w; v<=v; + +v ) for (int k=0; k*v<=v; + +k ) = Min (dp[i-1][v],dp[i-1][v-k*w]+p*
Law II:
1, Recursive Code: (interpretation of the classic code)
for (int i=0; i<n; + +i ) for (int j=w; j<=v; + +j ) = min (dp[j],dp[j-w]+p);
2. Space optimization:
Only with Dp[v], the state transition is: Dp[v]=min (Dp[v-k*w[i]] + k*p[i]), the first time loop, Dp[i][v] only rely on the state of Dp[i-1][v], the previous dp[0...i-1,v] are useless, the final output U is also in the DP [][v] to find results, so do not save these states. This requires saving two dp[0][v], Dp[1][v] to replace the two variables.
Further thinking, k=0, the equivalent of Dp[i][v]=dp[i-1][v], and then the enumeration k are compared with dp[i][v], that is, the first i-1 layer of the loop after the result of the second layer is equivalent to the initial state, so just maintain an array dp[v] is enough.
3, Time Optimization:
When using the article I, which is the layer I loop, using dp[v-w] to update dp[v], Dp[v-w] has been updated because the loop is updated as V = W to V, as follows:
Dp[v] = min (Dp[v] not updated, Dp[v-w] updated) +p)//update dp[v]
= Min (Dp[v] not updated, min (dp[v-w] not updated, dp[v-2w] updated +p) +p)//update dp[v-w]
= Min (Dp[v] not updated, Dp[v-w] not updated +p, min (dp[v-2w] not updated, dp[v-3w] updated +p) +2p)//update dp[v-2w]
= Min (Dp[v] not updated, Dp[v-w] not updated +p, dp[v-2w] not updated +2p, ..., dp[v-kw] not updated +KP)//update dp[v-3w]
= Min (Dp[v-k*w] not updated +k*p) (0<=K<=V/VI)
Complexity of the algorithm:
Time complexity O (NV), Space complexity O (n)
Algorithm steps
Step 1: Read into the data, initialize Dp[i] to infinity, dp[0]=0
Step 2: Recursive, recursive formula as above, the answer is DP[V]
Code:
#include <cstdio>#defineMin (A, b) (a<b)? a:bConst intINF = 1E9,MAXN =8000; intDP[MAXN];intMain () {intkase,v1,v, N; intP, W;//Value,weightscanf"%d",&Kase); while(kase--) {scanf (" %d%d%d",&v1,&v,&N); V-=V1; //Init for(intI=1;i<=v; ++i) dp[i]=inf; dp[0]=0; //DP for(intI=1; i<=n; ++i) {scanf ("%d%d",&p,&W); for(intJ=w; j<=v; ++j) {Dp[j]= Min (dp[j],dp[j-w]+p); } } //Output if(Dp[v]==inf) printf ("This is impossible.\n"); Elseprintf"The minimum amount of money in the Piggy-bank is%d.\n", Dp[v]); } return 0;}
POJ 1384piggy-bank Complete Backpack analysis