0/1 Knapsack CSES BookShop

Hi,

I am trying to solve Bookshop from CSES set.
I am using dynamic programming in bottom up fashion but still getting TLEs.

Any help/hints would be appreciated. If you were in my place, what would you change in my code.

    #include <bits/stdc++.h>
    // Common file
    #include <ext/pb_ds/assoc_container.hpp>
    #include <ext/pb_ds/tree_policy.hpp> 

    using namespace __gnu_pbds;
    using namespace std;


    using ll = long long;
    using pi = pair<int, int>;
    using ti = tuple<int, int, int>;
    using tl = tuple<ll, ll, ll>;
    using pil = pair<int, ll>;
    using pli = pair<ll, int>;
    using pl = pair<ll, ll>;
    using vi = vector<int>;
    using vl =  vector<ll>;
    using vpi = vector<pi>;
    using vpil = vector<pil>;
    using vpli = vector<pli>;
    using vpl = vector<pl>;
    using vti = vector<ti>;
    using vtl = vector<tl>;
    using vvi = vector<vi>;
    using vvl = vector<vl>;
    using vvpi = vector<vpi>;
    using vvpil = vector<vpil>;
    using vvpli = vector<vpli>;
    using vvpl = vector<vpl>;
    using vvti = vector<vti>;
    using vvtl = vector<vtl>;

    using ordered_set =  tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>;

    const int INF = INT_MAX;
    const ll LINF = LLONG_MAX;
    const int MOD = 1000000000 + 7;

    #define setbits(n) __builtin_popcount(n);
    #define sz(x) (int)size(x)

    const int C = (int)1e5;
    const int N = 1000;

    int dp[C+1][N+1];
    pair<int, int> pp[N+1];

    int knapsack(int n, int c) {
    	for (int i = 1; i <= c; i++) {
    		for (int j = 1; j <= n; j++) {
    			dp[i][j] = dp[i][j-1];
    			if (i >= pp[j].first) {
    				dp[i][j] = max(dp[i][j], dp[i-pp[j].first][j-1] + pp[j].second);
    			}
    		}
    	}
    	return dp[c][n];
    }

    int main() {
    	ios_base::sync_with_stdio(false);
    	cin.tie(nullptr);
    	int n, x;
    	cin >> n >> x;
    	for (int i = 1; i <= n; i++) {
    		cin >> pp[i].first;
    	}
    	for (int i = 1; i <= n; i++) {
    		cin >> pp[i].second;
    	}
    	cout << knapsack(n, x) << "\n";
    	return 0;
    }

Reduce the amount of memory to \mathcal O(N+X).

Thanks a lot for your feedback. Got AC.

Just for the reference; for others who might this find this thread useful, I’m posting my code below

// https://cses.fi/problemset/task/1158
#include <bits/stdc++.h>
// Common file
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp> 

using namespace __gnu_pbds;
using namespace std;


using ll = long long;
using pi = pair<int, int>;
using ti = tuple<int, int, int>;
using tl = tuple<ll, ll, ll>;
using pil = pair<int, ll>;
using pli = pair<ll, int>;
using pl = pair<ll, ll>;
using vi = vector<int>;
using vl =  vector<ll>;
using vpi = vector<pi>;
using vpil = vector<pil>;
using vpli = vector<pli>;
using vpl = vector<pl>;
using vti = vector<ti>;
using vtl = vector<tl>;
using vvi = vector<vi>;
using vvl = vector<vl>;
using vvpi = vector<vpi>;
using vvpil = vector<vpil>;
using vvpli = vector<vpli>;
using vvpl = vector<vpl>;
using vvti = vector<vti>;
using vvtl = vector<vtl>;

using ordered_set =  tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>;

const int INF = INT_MAX;
const ll LINF = LLONG_MAX;
const int MOD = 1000000000 + 7;

#define setbits(n) __builtin_popcount(n);
#define sz(x) (int)size(x)

const int C = (int)1e5;
const int N = 1000;

/* int dp[C+1][N+1]; */
int dp[2][C+1];
pair<int, int> pp[N+1];

int knapsack(int n, int c) {
	int k = 1;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= c; j++) {
			dp[k][j] = dp[1-k][j];
			if (j >= pp[i].first) {
				dp[k][j] = max(dp[k][j], dp[1-k][j-pp[i].first] + pp[i].second);
			}
		}
		k ^= 1;
	}
	k ^= 1;
	return dp[k][c];
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	int n, x;
	cin >> n >> x;
	for (int i = 1; i <= n; i++) {
		cin >> pp[i].first;
	}
	for (int i = 1; i <= n; i++) {
		cin >> pp[i].second;
	}
	cout << knapsack(n, x) << "\n";
	return 0;
}

macros galore