Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1-rivkms #5

Merged
merged 3 commits into from
Feb 15, 2024
Merged

1-rivkms #5

merged 3 commits into from
Feb 15, 2024

Conversation

rivkms
Copy link
Collaborator

@rivkms rivkms commented Feb 12, 2024

πŸ”— 문제 링크

ν‰λ²”ν•œ λ°°λ‚­

βœ”οΈ μ†Œμš”λœ μ‹œκ°„

1h

✨ μˆ˜λ„ μ½”λ“œ

🎷문제 μ„ μ • κ³Όμ •

λ‚˜λ¦„ 첫 μ‹œκ°„μ΄λ‹ˆκΉ κ·Έλ™μ•ˆ 많이 κ³΅λΆ€ν–ˆμ—ˆλ˜ DP, κ·Έμ€‘μ—μ„œλ„ knapsack 문제λ₯Ό 가지고 μ™”μŠ΅λ‹ˆλ‹€.

문제 이해

λ¬Έμ œμ—μ„œμ˜ μž…λ ₯은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

μ£Όμ–΄μ§€λŠ” μž…λ ₯
1. λ¬Όν’ˆμ˜ 수 N
2. 배낭에 넣을 수 μžˆλŠ” 무게 K
3. N 개의 물건의 무게 W
4. N 개의 물건의 κ°€μΉ˜ V

μœ„ 4가지 μž…λ ₯을 μ΄μš©ν•˜μ—¬ 배낭에 넣을 수 μžˆλŠ” μ΅œλŒ€μ˜ κ°€μΉ˜λ₯Ό μ°ΎλŠ” λ¬Έμ œμž…λ‹ˆλ‹€.

문제 풀이

일단 DPλ₯Ό ν’€κΈ° μœ„ν•˜μ—¬ μ–΄λ–»κ²Œ ν•˜λ©΄ μ΅œλŒ€μ˜ κ°€μΉ˜λ₯Ό κ°€μ§€λŠ”μ§€ 쑰금 더 μ§κ΄€μ μœΌλ‘œ μ•ŒκΈ° μœ„ν•΄ DP Table을 κ·Έλ €λ΄…μ‹œλ‹€.

1️⃣ 일반적인 경우 :
μœ„μ˜ ν‘œμ—μ„œ (3,7)의 값이 μ–΄λ–»κ²Œ λ‚˜μ˜€κ²Œ λ˜μ—ˆλŠ”μ§€ μƒκ°ν•΄λ³ΌκΉŒμš”?

  • (3,7)은 λ°°λ‚­μ˜ 크기가 7인 경우 1, 2, 3번 물건을 넣을 수 μžˆμ„ λ•Œ μ΅œλŒ€ κ°€μΉ˜

μš°λ¦¬λŠ” (2,7) κ³Ό (2,4)+3번째 물건의 κ°€μΉ˜ λ₯Ό λΉ„κ΅ν•˜μ—¬ κ·Έ 쀑 큰 것을 찾게 λ©λ‹ˆλ‹€.
κ·Έ κ²°κ³Ό 13 vs 8+6=14λ‘œμ„œ 14κ°€ 더 ν¬λ‹ˆ (3,7)μ—λŠ” 14 κ°€ λ“€μ–΄κ°€κ²Œ λ©λ‹ˆλ‹€.

2️⃣ νŠΉλ³„ν•œ 경우 :
μœ„μ˜ ν‘œμ—μ„œ (4,3)의 값을 λ³ΌκΉŒμš”?
4번째 물건의 무게인 5보닀 λ² λ‚­μ˜ 크기가 μž‘μ•„ ν•΄λ‹Ή 물건을 배낭에 넣지 λͺ»ν•©λ‹ˆλ‹€.
κ·Έλž˜μ„œ (3,3) 의 값이 λ°”λ‘œ λ‚΄λ €μ˜€κ²Œ 되겠죠.

βœ”οΈμ΄ ν‘œλ₯Ό Value라고 λͺ…λͺ…ν•  λ•Œ, 결과적으둜, λ‹€μŒμ˜ 관계식을 적을 수 μžˆμŠ΅λ‹ˆλ‹€.

Value[i][j] = Value[i-1][j] (Wi < j)
Value[i][j] = Max ( Value[i-1][j], Value[i-1][j-Wi] + Vi ) (Wi > j)

μœ„ 관계식을 잘 κ΅¬ν•΄λƒˆλ‹€λ©΄, 이젠 μ½”λ“œλ‘œ 짜기만 ν•˜λ©΄ λ©λ‹ˆλ‹€!!

μ½”λ“œ μž‘μ„±

1️⃣ μž…λ ₯값듀을 λšλ”± λ°›κ³ 
2️⃣ Value 배열을 λ§Œλ“  ν›„ 
3️⃣ i와 jλ₯Ό λŠ˜λ €κ°€λ©° μœ„μ—μ„œ κ΅¬ν–ˆλ˜ 관계식을 μ΄μš©ν•˜μ—¬ Value 배열을 μ±„μ›Œλ‚˜κ°‘λ‹ˆλ‹€. 
4️⃣ λμ—λŠ” Value[N][K]λ₯Ό 좜λ ₯ν•˜λ©΄ 
5️⃣ 문제 ν•΄κ²°!!

λ₯Ό μ½”λ“œλ‘œ μ“°λ©΄ λ‹€μŒκ³Ό κ°™κ² μ£ 

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;


int main(){
    int n, k;
    cin >> n >> k;
    vector<pair<int, int>> wv(n+1, pair<int, int>(0,0));
    vector<vector<int>> value (n+1, vector<int>(k+1, 0));
    for(int i = 1; i<=n; i++){
        cin >> wv[i].first >> wv[i].second;        
    }
    
    for(int i = 1; i<=n; i++){
        for(int j = 1; j<=k;j++){
            if(wv[i].first > j ){
                value[i][j] = value[i-1][j];
            }
            else{
                value[i][j] = max(value[i-1][j], value[i-1][j-wv[i].first]+wv[i].second);
            }
            
        }
    }
    cout << value[n][k];

    return 0;
}

πŸ“š μƒˆλ‘­κ²Œ μ•Œκ²Œλœ λ‚΄μš©

πŸ“’ λ§Œμ•½ 물건을 쀑볡할 수 μžˆλ‹€λ©΄ κ΄€κ³„μ‹μœΌλ‘œ ν’€λ©΄ 되겠죠?

Value[i][j] = Value[i-1][j] (Wi < j)
Value[i][j] = Max ( Value[i-1][j], Value[i][j-Wi] + Vi ) (Wi > j)

μ™œ κ·ΈλŸ°μ§€λŠ” ν•œλ²ˆ μƒκ°ν•΄λ³΄μ‹œκΈΈ

πŸ“’ 이 방법 외에도 λ‹€μ–‘ν•œ 방법이 μžˆλŠ” 것 κ°™μŠ΅λ‹ˆλ‹€.
이 κΈ€μ—μ„œ 잘 μ„€λͺ…ν•΄λ‘” 것 κ°™μ•„ μ²¨λΆ€ν•΄λ΄…λ‹ˆλ‹€.
[μ•Œκ³ λ¦¬μ¦˜ - 이둠] 0-1 KnapSack Problem and Fractional

ν•œλ²ˆ μ°Έκ³ ν•΄λ³΄μ‹œλ©΄ 쒋을 것 κ°™μŠ΅λ‹ˆλ‹€.

πŸ“ 제 μ½”λ“œλ₯Ό 쑰금 더 κ°œμ„ ν•΄λ³΄μžλ©΄,
1️⃣ μœ„μ˜ ν‘œμ—μ„œ 맨 처음 0인 κ°’λ“€ μ—†μ• κΈ° -> 물건의 무게의 μ΅œμ†Œκ°’μ„ κΈ°μ€€μœΌλ‘œ 자λ₯΄κΈ°
2️⃣ 2차원 배열을 μ‚¬μš©ν•˜μ§€ μ•Šκ³  1차원 λ°°μ—΄λ‘œ ν’€κΈ°

등등이 μžˆμ„ 것 κ°™λ„€μš”

@kjs254 kjs254 requested review from kjs254 and removed request for kjs254 February 14, 2024 05:18
Copy link
Member

@kjs254 kjs254 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DP table을 ν†΅ν•œ μ„€λͺ…이 μ‹œκ°μ μœΌλ‘œ μ΄ν•΄ν•˜κΈ° μ•„μ£Ό μ’‹μ•˜μŠ΅λ‹ˆλ‹€. πŸ‘

문제λ₯Ό 처음 μ§λ©΄ν–ˆμ„ λ•Œ νƒμš•λ²•μ΄ μ§κ΄€μ μœΌλ‘œ λ– μ˜¬λžλŠ”λ° μ°Έκ³  글을 μ½μ–΄λ³΄λ‹ˆ λ¬Όν’ˆμ΄ λΆ„ν•  κ°€λŠ₯ν•  λ•Œ νƒμš•λ²•μ„ μ‚¬μš©ν•œλ‹€λŠ” 점을 μ•Œκ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

이번 풀이λ₯Ό 톡해 DP μ•Œκ³ λ¦¬μ¦˜μ„ 곡뢀할 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. μˆ˜κ³ ν•˜μ…¨μŠ΅λ‹ˆλ‹€β—β—β—

Comment on lines +8 to +24
int main(){
int n, k;
cin >> n >> k;
vector<pair<int, int>> wv(n+1, pair<int, int>(0,0));
vector<vector<int>> value (n+1, vector<int>(k+1, 0));
for(int i = 1; i<=n; i++){
cin >> wv[i].first >> wv[i].second;
}

for(int i = 1; i<=n; i++){
for(int j = 1; j<=k;j++){
if(wv[i].first > j ){
value[i][j] = value[i-1][j];
}
else{
value[i][j] = max(value[i-1][j], value[i-1][j-wv[i].first]+wv[i].second);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

μ œκ°€ c++μ—μ„œ μ½”λ“œκ΅¬ν˜„μ΄ μ΅μˆ™ν•˜μ§€ μ•Šμ•„ μ—¬μ­€λ³΄μžλ©΄

μœ„μ˜ λΈ”λŸ­μ—μ„œ μž…λ ₯값을 λ°›κ³  value 배열을 μƒμ„±ν•œ λ’€,

μ•„λž˜ forλ¬Έμ—μ„œ 관계식을 μ΄μš©ν•˜μ—¬ value 배열을 μ±„μ›Œλ‚˜κ°„λ‹€κ³  μ΄ν•΄ν•˜λ©΄ λ κΉŒμš”?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

λ„΅ valueκ°€ DP Table이라고 λ³΄μ‹œλ©΄ 되고 DP Table을 관계식을 μ΄μš©ν•΄μ„œ μ±„μ›Œλ‚˜κ°„λ‹€κ³  μƒκ°ν•˜μ‹œλ©΄ λ©λ‹ˆλ‹€ 😁

@miniron-v
Copy link
Member

miniron-v commented Feb 14, 2024

PR 잘 λ΄€μŠ΅λ‹ˆλ‹€! 잘 μ§œμ—¬μ§„ 점화식과 μ„€λͺ…μ—μ„œ, μ–Όλ§ˆλ‚˜ μ—΄μ‹¬νžˆ κ³΅λΆ€ν•˜μ…¨λŠ”μ§€κ°€ 잘 λ“œλŸ¬λ‚˜λ„€μš”.

저도 저희 νŒ€(5νŒ€) PRμ—μ„œ 이 문제λ₯Ό 보고 ν’€μ–΄λ΄€λŠ”λ°, λ§Žμ€ κΉ¨λ‹¬μŒμ„ 얻을 수 있던 λ¬Έμ œμ˜€μŠ΅λ‹ˆλ‹€.

AlgoLeadMe/AlgoLeadMe-5#55

#include <iostream>
#include <vector>
#include <algorithm>

bool compare(std::pair<int, int> a, std::pair<int, int> b) {
	return a.first < b.first;
}

int main() {
	// μž…λ ₯
	int n, k;
	std::cin >> n >> k;

	std::vector<std::pair<int, int>> stuff(n);
	for (int i = 0; i < n; ++i) {
		std::cin >> stuff[i].first >> stuff[i].second;
	}

	std::sort(stuff.begin(), stuff.end(), compare);

	// dp
	std::vector<int> max_cost(k + 1, 0);

	for (auto& s : stuff) {
		for (int i = k; i >= 1; --i) {
			if (i - s.first < 0) {
				break;
			}

			if (max_cost[i - s.first] + s.second > max_cost[i]) {
				max_cost[i] = max_cost[i - s.first] + s.second;
			}
		}
	}

	std::cout << max_cost[k];
}

2차원 λ°°μ—΄μ˜ 행을 μˆœμ„œλŒ€λ‘œ 봀을 λ•Œ, 항상 μ•„λž˜μͺ½ 행이 μœ„μͺ½ 행보닀 값이 큰 사싀을 λ°œκ²¬ν•  수 있죠. κ²Œλ‹€κ°€ 항상 λ°”λ‘œ μœ„ ν–‰λ§Œ μ ‘κ·Όν•˜λ‹ˆ, λ¦¬νŒ©ν† λ§ 쀑 ν•œ 쀄 배열이면 μΆ©λΆ„ν•˜κ² λ‹€λΌλŠ” 생각이 금방 λ“€ 것 κ°™μ•„μš”. (λ§ˆμ§€λ§‰ 행을 μ œμ™Έν•˜λ©΄ κΈ°μ–΅ν•  ν•„μš”κ°€ μ—†μœΌλ‹ˆκΉŒμš”.)

첫 PR인데도 μƒμ„Έν•˜κ³  λͺ…ν™•ν•œ μ„€λͺ… κ°μ‚¬λ“œλ¦½λ‹ˆλ‹€. κ³ μƒν•˜μ…¨μ–΄μš”!

Copy link
Collaborator

@YIM2UL2ET YIM2UL2ET left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

쒋은 아이디어에 그것을 μ½”λ“œλ‘œ κ΅¬ν˜„ν•œ 것도 ν μž‘μ„ κ³³ μ‘°μ°¨ μ—†λ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. μˆ˜κ³ ν•˜μ…¨μŠ΅λ‹ˆλ‹€!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그림이 μžˆμœΌλ‹ˆκΉ μ•Œκ³ λ¦¬μ¦˜ 이해가 ν™•μ‹€νžˆ μž˜λ˜λ„€μš”. 덕뢄에 쒋은 아이디어 ν•˜λ‚˜ μ–»κ³  κ°‘λ‹ˆλ‹€!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants