Today I encountered a problem poj2184. The idea is to calculate the optimal solution that meets the requirements after the DP OF THE 01 backpack. However, when solving the backpack, a problem occurs: the volume has a negative number, so there will be two problems in the DP process: the volume is out of the range during the cycle; state transition equation during space compression: DP [v] = max (DP [v], DP [V-C [I] + W [I]), when C [I] is a negative value, V-C [I]> V. In this way, the calculation is repeated from large to bottom in the general loop direction.
First, let's look at the second question. In the general 01 backpack space compression, the volume traversal is from large to small, because DP [v] = max (DP [v], DP [V-C [I] + W [I]). The current DP [v] only depends on the smaller DP [V-C [I], therefore, DP [V-C [I] and DP [v] are in the last state from large to small times.
If the volume is negative V-C [I]> V, traverse DP [V-C [I] from large to small is the current item status, not the previous one, in this case, an error occurs. The solution is to traverse from small to large.
For the first problem, the entire number axis is translated during processing so that all possible conditions are positive.
For example, calculate the data range first:
A total of 100 groups, from-1000 to 1000, then the volume range is-100*1000 to 100*1000. After translation, the range of data to be processed is between 0 and 200000, and the new origin is changed to 100000.
Initialization changes:
for(int i=0;i<=200000;i++) dp[i]=-INF; dp[100000]=0;
Cycle:
For (INT I = 1; I <= N; I ++) {If (s [I]> 0) {for (INT v = 200000; v> = s [I]; V --) // from the maximum possible value to the minimum value {If (DP [V-s [I]>-INF) DP [v] = max (DP [v], DP [V-s [I] + F [I]) ;}} else {for (INT V = 0; v-s [I] <= 200000; V ++) {If (DP [V-s [I]>-INF) DP [v] = max (DP [v], DP [V-s [I] + F [I]) ;}}
The calculation result should be traversed from 100000, because 100000 is equivalent to the original 0
int nMax=0; for(int v=100000;v<=200000;v++) if(dp[v]>=0) nMax=max(nMax,dp[v]+v-100000);
There is also a solution to this problem: increase the size of all items by 1000 so that they are all greater than 0, then, when DP is used to record DP [I] [v] With an array, an additional 1000 is added, and then the result is subtracted. Note that status transfer is changed:
For (INT I = 1; I <= N; I ++) for (INT v = sum; V> = s [I]; V --) // 1000 more if (DP [v]-tot [v] * 1000 <DP [V-s [I] + F [I]-(1 + tot [V-s [I]) * 1000) {DP [v] = DP [V-s [I] + F [I]; TOT [v] = tot [V-s [I] + 1 ;}
Instead
if(dp[v]<dp[v-s[i]]+f[i]) { dp[v]=dp[v-s[i]]+f[i]; tot[v]=tot[v-s[i]]+1; }
Because the maximum value is a V + dp [v]-tot [v] * 1000, when V1 is set, DP [v]-tot [v] * 1000 indicates the maximum value, although the meaning of this maximum value is hard to understand ..
The second solution to this question is just a rough understanding of the Final Report. Dynamic Planning is amazing ....