Submission #52670320


Source Code Expand

#include <bits/stdc++.h> 
using namespace std;  

typedef long long ll;  
typedef pair<int, int> ii;  

template<typename T>
bool maximize(T& a, const T& b) {
	if (b < a) return false; 
	a = b; 
	return true; 
}

const int INF = 1e9;  
const ll LINF = 1e18;  

// dp knapsack 
// Bài toán gốc: 
// Cho n đồ vật và một balo có khối lượng là S, mỗi đồ vật là có 2 tham số là:   
// w(i): khối lượng của vật thứ i   
// v(i): giá trị của vật thứ i   
// Yêu cầu chọn ra một số món vật sao cho tổng khối lượng w(i) không vượt quá S và tổng giá trị v(i) là lớn nhất?

const int N = 1e2 + 5; 
const int S = 1e5 + 5;    

int n, s;  
int w[N], v[N];  
ll ans;   

void backtrack(int i, ll sum_w, ll sum_v) { // O(2^n)
	if (i == n + 1) {
		ans = max(ans, sum_v);  
		return; 
	}

	// không chọn món vật thứ i   
	backtrack(i + 1, sum_w, sum_v);  

	// chọn món vật thứ i 
	if (sum_w + w[i] <= S) {
		backtrack(i + 1, sum_w + w[i], sum_v + v[i]); 
	}
}

ll dp[2][S]; // dp[i][j] = tổng giá trị v(i) lớn nhất
  			  // 		   khi xét i món vật đầu tiên, tổng khối lượng w(i) của các món vật đã chọn là j 

ll memo[N][S]; 

ll f(int i, int j) {
	if (i == 0) return 0;   

	ll& ans = memo[i][j];   
	if (ans != -1) return ans;   

	// không chọn món vật thứ i
	ans = -LINF;   
	maximize(ans, f(i - 1, j));  

	// chọn món vật thứ i 
	if (j - w[i] >= 0) maximize(ans, f(i - 1, j - w[i]) + v[i]); 

	return ans; 
}	

int main() {
	ios::sync_with_stdio(0); cin.tie(0);  	
	cin >> n >> s;  
	for (int i = 1; i <= n; i++) {
		cin >> w[i] >> v[i]; 
	} 

	// ans = -LINF;  
	// backtrack(1, 0, 0); 
	// cout << ans << '\n'; 

	for (int j = 0; j <= s; j++) dp[0][j] = -LINF;  

	dp[0][0] = 0;   
	// O(n * S)
	for (int i = 1; i <= n; i++) {
		for (int j = 0; j <= s; j++) dp[i % 2][j] = -LINF;  
		dp[i % 2][0] = 0;   
			
		for (int j = 0; j <= s; j++) {
			dp[i % 2][j] = dp[(i - 1) % 2][j]; 
			if (j - w[i] >= 0) maximize(dp[i % 2][j], dp[(i - 1) % 2][j - w[i]] + v[i]); 
		}

	}

	ll ans = 0;   
	for (int j = 0; j <= s; j++) {
		maximize(ans, dp[n % 2][j]); 
	}

	cout << ans << '\n'; 

	// memset(memo, -1, sizeof memo);   

	// ll ans = 0;  
	// for (int j = 0; j <= s; j++) maximize(ans, f(n, j)); 

	// cout << ans << '\n'; 
}

Submission Info

Submission Time
Task D - Knapsack 1
User Euthymia
Language C++ 20 (gcc 12.2)
Score 100
Code Size 2470 Byte
Status AC
Exec Time 22 ms
Memory 5140 KiB

Judge Result

Set Name All
Score / Max Score 100 / 100
Status
AC × 13
Set Name Test Cases
All 0_00, 0_01, 0_02, 1_00, 1_01, 1_02, 1_03, 1_04, 1_05, 1_06, 1_07, 1_08, 1_09
Case Name Status Exec Time Memory
0_00 AC 1 ms 3456 KiB
0_01 AC 1 ms 3448 KiB
0_02 AC 1 ms 3516 KiB
1_00 AC 2 ms 5072 KiB
1_01 AC 14 ms 5080 KiB
1_02 AC 15 ms 4960 KiB
1_03 AC 18 ms 5060 KiB
1_04 AC 21 ms 5068 KiB
1_05 AC 22 ms 5040 KiB
1_06 AC 22 ms 5076 KiB
1_07 AC 22 ms 5140 KiB
1_08 AC 18 ms 5140 KiB
1_09 AC 15 ms 4976 KiB