HihoCoder-1038-01 backpack (Classic dynamic planning problem !!)
#1038: 01 backpack time limit: 20000 ms single point time limit: 1000 ms memory limit: 256 MB
Description
In addition, in the story of the previous week, Xiao Hi and Xiao Ho finally got a large number of coupons! Now, it's time for Mr. Ho to get the rewards!
Mr. Ho now has M coupons, and N prizes in the prize area are marked as 1 to N respectively. Among them, the I-th prize must be exchanged with the need (I) coupon, at the same time, it can only be exchanged once. In order to avoid wasting the hard-earned coupons, Xiao Ho scored points for each prize, the I-th prize is rated as value (I), indicating his preference for the prize. Now he wants to know which prizes can be exchanged Based on the coupons he receives, so that the sum of the favorite values of these prizes can be maximized.
Tip 1: reasonable abstraction and State definition are the most critical steps in dynamic planning.
Tip 2: we have talked about how to reduce the time consumption. Let's take a look at how to reduce the space consumption.
Input
Each test point (input file) has only one set of test data.
The first act of each group of test data is two positive integers N and M, indicating the number of prizes and the number of prizes in the small Ho hands.
The next n rows describe each row to describe a prize. The I behavior contains two integers: need (I) and value (I). The meaning is described in the previous article.
Test data guarantee
For 100% of data, the value of N cannot exceed 500, and the value of M cannot exceed 10 ^ 5.
For 100% of data, need (I) cannot exceed 2*10 ^ 5, and value (I) cannot exceed 10 ^ 3
Output
For each group of test data, an integer Ans is output, indicating the total preference value that small Ho can obtain.
-
Sample Input
-
5 1000144 990487 436210 673567 581056 897
-
Sample output
-
2099
What I was most afraid of doing at first was the DP question, because I have never learned too well, and now I have not learned too well ..
DP:
What is a subproblem?
First, we need to find a way to abstract the problems we have encountered!
The best (I, x) indicates whether to select the first I item. If the total number of coupons required for the currently selected item cannot exceed x, the sum of the highest values that can be obtained.
So there are best (N, M) = max {best (N-1, M-need (N) + value (N), best (N-1, M )}!
For any I> 1, j, we can all know best (I, j) = max {best (I-1, j-need (I) + value (I ), best (I-1, j )}!
This 01 backpack problem can be divided into two dimensions and one dimension, which is actually more clever.
Two-dimensional AC code (672 ms, 200 MB ):
# Include
# Include
# Include using namespace std; int dp [502] [100002]; int need [502], value [502]; int main () {int n, m; while (scanf (% d, & n, & m )! = EOF) {for (int I = 1; I <= n; I ++) scanf (% d, & need [I], & value [I]); for (int j = 0; j <= m; j ++) dp [0] [j] = 0; for (int I = 1; I <= n; I ++) for (int j = 0; j <= m; j ++) if (j
One-dimensional AC code:
#include
#include
#include using namespace std;int dp[100005];int need[502], value[502];int main(){int n, m;while(scanf(%d %d, &n, &m) != EOF){for(int i=1; i<=n; i++)scanf(%d %d, &need[i], &value[i]);memset(dp, 0, sizeof(dp));for(int i=1; i<=n; i++)for(int j=m; j>=need[i]; j--)dp[j] = max(dp[j], dp[j-need[i]] + value[i]);printf(%d, dp[m]);}return 0;}