제출 #497274

#제출 시각아이디문제언어결과실행 시간메모리
497274RandomLBKnapsack (NOI18_knapsack)C++17
100 / 100
41 ms3552 KiB
#include <bits/stdc++.h> #pragma GCC optimize("O3", "unroll-loops") #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt") using namespace std; typedef long long ll; typedef unsigned long long ull; typedef long double ld; typedef pair<int, int> pi; typedef pair<ll, ll> pll; typedef pair<double, double> point; typedef tuple<int, int, int> tp; //-------LL typedef unordered_set<ll> uset; typedef priority_queue<pll, vector<pll>, greater<pll>> djk; typedef long long C; typedef complex<C> P; #define pb push_back #define ms(a,b) memset(a,b,sizeof(a)) #define maxE(a) *max_element(a, a+sizeof(a)/sizeof(a[0])) #define minE(a) *min_element(a, a+sizeof(a)/sizeof(a[0])) #define F first #define S second #define siz(a) (int)a.size() #define len(a) (int)a.length() #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() #define bits(x) __builtin_popcount(x) #define vvll vector<vector<ll>> #define FOR(a, n) for (int a = 0; a < n; a++) #define fin(s) {cout << s << "\n"; return;} #define finm(s) {cout << s << "\n"; return 0;} #define X real() #define Y imag() #define deb(...) logger(#__VA_ARGS__, __VA_ARGS__) template<typename ...Args> void logger(string vars, Args&&... values) { cout << vars << " = "; string delim = ""; (..., (cout << delim << values, delim = ", ")); cout << endl; } template<class T> istream& operator >> (istream& is, complex<T>& p) { T value; is >> value; p.real(value); is >> value; p.imag(value); return is; } const int INF = 0x3f3f3f3f; const ll LLINF = 0x3f3f3f3f3f3f3f3f; const ll MOD = 1e9+7; const double pie = 2*acos(0.0); //------------------------------------------------------------ const int MAX = 2005; int dp[MAX]; vector<pi> use[MAX]; int main(){ //Key observation: since there only items of up to W 2000, there are bound //to be some duplicate weights. We greedily take the largest value for each weight, //and we stop considering items of a certain weight after we already have the max //possible items(2000/W) of that weight that can be used to fill up the knapsack. cin.tie(0)->sync_with_stdio(0); int s, n; cin >> s >> n; bool curr = 1; for (int i = 1; i <= n; i++){ int v, w, k; cin >> v >> w >> k; use[w].pb({v, k}); //Sort by the values of item } for (int i = 1; i <= s; i++){ sort(rall(use[i])); int curr = 0; //Keep track of how many items of the weight we have already for (int j = 0; j < siz(use[i]); j++){ curr += use[i][j].S; if (curr >= s/i){ //If we already have the max possible items needed, we don't need to consider while (siz(use[i]) > j+1) use[i].pop_back(); //the rest of the items with lower value for the same W break; } } } //Normal knapsack afterwards for (int i = 1; i <= s; i++){ //Go through items of each weight for (auto[v, k]: use[i]){ //Choose items in powers of 2 k = min(k, s/i); int curr = 0; while (k){ int sz = min((1<<curr), k); curr++; for (int j = s; j >= i*sz; j--) dp[j] = max(dp[j], dp[j-i*sz] + sz*v); k -= sz; } } } cout << dp[s] << "\n"; } /* stuff you should look for * int overflow, array bounds * test case inputs don't carry over (DON'T RETURN EARLY) * special cases (n=1?) * do smth instead of nothing and stay organized * WRITE STUFF DOWN * DON'T GET STUCK ON ONE APPROACH */

컴파일 시 표준 에러 (stderr) 메시지

knapsack.cpp: In function 'int main()':
knapsack.cpp:64:10: warning: unused variable 'curr' [-Wunused-variable]
   64 |     bool curr = 1;
      |          ^~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...