E - Knapsack 2
Time Limit: 2 sec / Memory Limit: 1024 MB
Score : 100100 points
Problem Statement
There are NN items, numbered 1,2,…,N1,2,…,N. For each ii (1≤i≤N1≤i≤N), Item ii has a weight of wiwi and a value of vivi.
Taro has decided to choose some of the NN items and carry them home in a knapsack. The capacity of the knapsack is WW, which means that the sum of the weights of items taken must be at most WW.
Find the maximum possible sum of the values of items that Taro takes home.
Constraints
- All values in input are integers.
- 1≤N≤1001≤N≤100
- 1≤W≤1091≤W≤109
- 1≤wi≤W1≤wi≤W
- 1≤vi≤1031≤vi≤103
Input
Input is given from Standard Input in the following format:
NN WW w1w1 v1v1 w2w2 v2v2 :: wNwN vNvN
Output
Print the maximum possible sum of the values of items that Taro takes home.
Sample Input 1 Copy
3 8 3 30 4 50 5 60
Sample Output 1 Copy
90
Items 11 and 33 should be taken. Then, the sum of the weights is 3+5=83+5=8, and the sum of the values is 30+60=9030+60=90.
Sample Input 2 Copy
1 1000000000 1000000000 10
Sample Output 2 Copy
10
Sample Input 3 Copy
6 15 6 5 5 6 6 4 6 6 3 5 7 2
Sample Output 3 Copy
17
Items 2,42,4 and 55 should be taken. Then, the sum of the weights is 5+6+3=145+6+3=14, and the sum of the values is 6+6+5=176+6+5=17.
题目链接:https://atcoder.jp/contests/dp/tasks/dp_e
思路:体积虽然很huge,但价值很小。把最大化价值,转成最小化体积,就还是原来的01背包了。(RUSH_D_CAT大佬指点的)
很不错的一个背包优化的思路,细节见我的代码。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #include <vector> #define sz(a) int(a.size()) #define all(a) a.begin(), a.end() #define rep(i,x,n) for(int i=x;i<n;i++) #define repd(i,x,n) for(int i=x;i<=n;i++) #define pii pair<int,int> #define pll pair<long long ,long long> #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) #define MS0(X) memset((X), 0, sizeof((X))) #define MSC0(X) memset((X), '\0', sizeof((X))) #define pb push_back #define mp make_pair #define fi first #define se second #define eps 1e-6 #define gg(x) getInt(&x) using namespace std; typedef long long ll; inline void getInt(int* p); const int maxn=1000010; const int inf=0x3f3f3f3f; /*** TEMPLATE CODE * * STARTS HERE ***/ ll dp[maxn]; ll n,W; ll v[maxn]; ll w[maxn]; int main() { memset(dp,0x3f,sizeof(dp)); gbtb; cin>>n>>W; repd(i,1,n) { cin>>w[i]>>v[i]; } ll ans=0ll; dp[0]=0; repd(i,1,n) { for(int j=1e5;j>=v[i];--j) { { dp[j]=min(dp[j],dp[j-v[i]]+w[i]); if(dp[j]<=W) ans=max(ans,(ll)(j)); } } } cout<<ans<<endl; return 0; } inline void getInt(int* p) { char ch; do { ch = getchar(); } while (ch == ' ' || ch == '\n'); if (ch == '-') { *p = -(getchar() - '0'); while ((ch = getchar()) >= '0' && ch <= '9') { *p = *p * 10 - ch + '0'; } } else { *p = ch - '0'; while ((ch = getchar()) >= '0' && ch <= '9') { *p = *p * 10 + ch - '0'; } } }