Algorithm/λ¬Έμ œν’€μ΄

[λ°±μ€€] 11501번 - 주식 (C++)

moaoh 2023. 7. 4. 20:46

문제

ν™μ€€μ΄λŠ” μš”μ¦˜ 주식에 λΉ μ Έμžˆλ‹€. κ·ΈλŠ” 미래λ₯Ό λ‚΄λ‹€λ³΄λŠ” 눈이 λ›°μ–΄λ‚˜, λ‚  λ³„λ‘œ μ£Όκ°€λ₯Ό μ˜ˆμƒν•˜κ³  μ–Έμ œλ‚˜ 그게 λ§žμ•„λ–¨μ–΄μ§„λ‹€. 맀일 κ·ΈλŠ” μ•„λž˜ μ„Έ κ°€μ§€ 쀑 ν•œ 행동을 ν•œλ‹€.

  1. 주식 ν•˜λ‚˜λ₯Ό μ‚°λ‹€.
  2. μ›ν•˜λŠ” 만큼 κ°€μ§€κ³  μžˆλŠ” 주식을 νŒλ‹€.
  3. 아무것도 μ•ˆν•œλ‹€.

ν™μ€€μ΄λŠ” 미래λ₯Ό μ˜ˆμƒν•˜λŠ” λ›°μ–΄λ‚œ μ•ˆλͺ©μ„ κ°€μ‘Œμ§€λ§Œ, μ–΄λ–»κ²Œ ν•΄μ•Ό μžμ‹ μ΄ μ΅œλŒ€ 이읡을 얻을 수 μžˆλŠ”μ§€ λͺ¨λ₯Έλ‹€. λ”°λΌμ„œ λ‹Ήμ‹ μ—κ²Œ λ‚  λ³„λ‘œ μ£Όμ‹μ˜ 가격을 μ•Œλ €μ£Όμ—ˆμ„ λ•Œ, μ΅œλŒ€ 이읡이 μ–Όλ§ˆλ‚˜ λ˜λŠ”μ§€ 계산을 해달라고 λΆ€νƒν–ˆλ‹€.

예λ₯Ό λ“€μ–΄ λ‚  μˆ˜κ°€ 3일이고 λ‚  λ³„λ‘œ μ£Όκ°€κ°€ 10, 7, 6일 λ•Œ, μ£Όκ°€κ°€ 계속 κ°μ†Œν•˜λ―€λ‘œ μ΅œλŒ€ 이읡은 0이 λœλ‹€. κ·ΈλŸ¬λ‚˜ λ§Œμ•½ λ‚  λ³„λ‘œ μ£Όκ°€κ°€ 3, 5, 9일 λ•ŒλŠ” 처음 두 날에 주식을 ν•˜λ‚˜μ”© 사고, λ§ˆμ§€λ§‰λ‚  λ‹€ νŒ”μ•„ 버리면 이읡이 10이 λœλ‹€.


μž…λ ₯

μž…λ ₯의 첫 μ€„μ—λŠ” ν…ŒμŠ€νŠΈμΌ€μ΄μŠ€ 수λ₯Ό λ‚˜νƒ€λ‚΄λŠ” μžμ—°μˆ˜ Tκ°€ μ£Όμ–΄μ§„λ‹€. 각 ν…ŒμŠ€νŠΈμΌ€μ΄μŠ€ λ³„λ‘œ 첫 μ€„μ—λŠ” λ‚ μ˜ 수λ₯Ό λ‚˜νƒ€λ‚΄λŠ” μžμ—°μˆ˜ N(2 ≤ N ≤ 1,000,000)이 μ£Όμ–΄μ§€κ³ , λ‘˜μ§Έ μ€„μ—λŠ” λ‚  별 μ£Όκ°€λ₯Ό λ‚˜νƒ€λ‚΄λŠ” N개의 μžμ—°μˆ˜λ“€μ΄ 곡백으둜 κ΅¬λΆ„λ˜μ–΄ μˆœμ„œλŒ€λ‘œ μ£Όμ–΄μ§„λ‹€. λ‚  별 μ£Όκ°€λŠ” 10,000μ΄ν•˜λ‹€.


좜λ ₯

각 ν…ŒμŠ€νŠΈμΌ€μ΄μŠ€ λ³„λ‘œ μ΅œλŒ€ 이읡을 λ‚˜νƒ€λ‚΄λŠ” μ •μˆ˜ ν•˜λ‚˜λ₯Ό 좜λ ₯ν•œλ‹€. 닡은 λΆ€ν˜ΈμžˆλŠ” 64bit μ •μˆ˜ν˜•μœΌλ‘œ ν‘œν˜„ κ°€λŠ₯ν•˜λ‹€.


 

예제 μž…λ ₯ 1 λ³΅μ‚¬

3
3
10 7 6
3
3 5 9
5
1 1 3 1 2

예제 좜λ ₯ 1 λ³΅μ‚¬

0
10
5

 


풀이과정

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

int		main(void)
{
	int t, n, temp, max, m;
	std::vector <int> v;

	std::cin >> t;
	for(int i = 0; i < t; i++)
	{
		std::cin >> n;
		for(int j = 0; j < n; j++) {
			std::cin >> temp;
			v.push_back(temp);
		}
		m = 0;
		for (int k = 0; k < v.size(); k++) {
			max = 0;
			for(int j = k; j < v.size(); j++) {
				if (max < v[j]) max = v[j];
			}
			if (v[k] < max) m += max - v[k];
		}
		std::cout << m << "\n";
		v.clear();
	}

	return (0);
}

λ¬Έμ œμ—μ„œ μ‹œκ°„μ œν•œμ΄ 5초둜 μ£Όμ–΄μ‘ŒκΈΈλž˜ μ—„μ²­ λ„‰λ„‰ν•˜λ‹€λΌκ³  μƒκ°ν–ˆμ—ˆλŠ”λ° 

2쀑 forλ¬Έ λ°©μ‹μœΌλ‘œ nλ§ŒνΌμ„ 2λ²ˆλ„λ‹ˆ O(N^2)의 μ‹œκ°„μ΄ λ˜μ–΄ μ‹œκ°„μ΄ˆκ³Όκ°€ λ°œμƒμ΄ λ˜μ—ˆλ˜ κ±° κ°™λ‹€.

μ΄ν›„λ‘œ μ½”λ“œλŠ” κ·ΈλŒ€λ‘œ 두고 μ‹œκ°„μ„ μ–΄λ–»κ²Œ 쀄일 수 μžˆμ„μ§€ 고민을 ν•˜λ‹€κ°€ 2쀑 forλ¬Έ λΆ€λΆ„μ—μ„œ ν˜„μž¬ κ²€μ‚¬ν•˜λŠ” (v[k]) κ°’ μ΄ν›„λ‘œ κ°€μž₯ 큰 값을 μ°ΎλŠ” μ € 파트λ₯Ό algorithm λ§€μ†Œλ“œμ— λ‚΄μž₯μ΄λ˜μ–΄μžˆλŠ” κ°€μž₯ 큰 값을 λ°”κΎΈλŠ” ν•¨μˆ˜λ‘œ λ°”κΎΈλ©΄ μ‹œκ°„μ΄ˆκ³Όκ°€ λ°œμƒν•˜μ§€ μ•Šμ§€μ•Šμ„κΉŒλΌλŠ” 생각을 κ°€μ§€κ³ 

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

int		main(void)
{
	int t, n, temp, max;
	long long m;
	std::vector <long long> v;

	std::cin >> t;
	for(int i = 0; i < t; i++)
	{
		std::cin >> n;
		for(int j = 0; j < n; j++) {
			std::cin >> temp;
			v.push_back(temp);
		}
		m = 0;
		for (int k = 0; k < v.size(); k++) {
			max = *std::max_element(v.begin() + k, v.end());
			if (v[k] < max) m += max - v[k];
		}
		std::cout << m << "\n";
		v.clear();
	}

	return (0);
}

max_element ν•¨μˆ˜λ₯Ό μ¨κ°€λ©΄μ„œ μ‚¬μš©μ„ ν•΄λ΄€λŠ”λ°

κ²°κ³ΌλŠ” λ˜‘κ°™μ΄ μ‹œκ°„μ΄ˆκ³Όκ°€ λ°œμƒμ΄ λ˜μ—ˆλ‹€. 곰곰이 생각을 ν•΄λ³΄λ‹ˆ max_elementλΌλŠ” ν•¨μˆ˜μžμ²΄λ„ λ‚΄λΆ€μ—μ„œλŠ”

λ‚΄κ°€ κ΅¬ν˜„ν•œ vectorλ₯Ό λŒμ•„μ„œ 큰값을 μ°ΎλŠ” 것과 둜직이 크게 λ‹€λ₯΄μ§€λŠ” μ•Šμ„κ±° κ°™λ‹€λŠ” 생각이 λ“€μ–΄μ„œ μ‹œκ°„λ³΅μž‘λ„μ—λŠ” 차이가 생기지 μ•ŠλŠ”λ‹€κ³  생각을 κ°€μ§€κ²Œ λ˜μ—ˆκ³ , μ € 문제λ₯Ό ν’€κΈ°μœ„ν•΄μ„œλŠ” O(N^2) ν˜•μ‹μ€ λΆˆκ°€λŠ₯ν•˜κ³  O(N)μ΄μ–΄μ•Όλ§Œ ν’€ 수 μžˆκ² λ‹€λΌλŠ” 생각이 λ“€μ–΄μ„œ 2쀑 for문을 μ œκ±°ν•˜κΈ°μœ„ν•΄μ„œ μƒˆλ‘­κ²Œ λ‘œμ§μ„ μƒκ°ν•˜κ²Œ λ˜μ—ˆλ‹€. 고민을 ν•˜λ‹€κ°€ λ‚˜μ˜¨ 둜직이 μ•„λž˜μ— λ‚˜μ™€μžˆλŠ” 이 λ‘œμ§μ΄λ‹€.

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

int		main(void)
{
	int t, n;
	long long m, temp, max;
	std::vector <long long> v;

	std::cin >> t;
	for(int i = 0; i < t; i++)
	{
		std::cin >> n;
		for(int j = 0; j < n; j++) {
			std::cin >> temp;
			v.push_back(temp);
		}
		m = 0;
		max = 0;
		for (int k = v.size() - 1; k >= 0; k--) {
			if (v[k] > max) max = v[k];
			else if (v[k] < max) m += max - v[k];
		}
		std::cout << m << "\n";
		v.clear();
	}

	return (0);
}

이 λ‘œμ§μ€ 2쀑 forλ¬Έ λŒ€μ‹  배열을 μ—­μˆœμœΌλ‘œ λŒμ•„μ„œ 큰 κ°’(max)λ₯Ό κ°±μ‹ ν•΄κ°€λ©° 진행이 되고 큰 κ°’(max) μ΄ν›„λ‘œ λ‚˜μ˜€λŠ” μž‘μ€ 값은 주식이 μ˜¬λžλ‹€λŠ” 말과 같은 μ˜λ―Έκ°€ λ˜λ―€λ‘œ max(큰값) - v[k](ν˜„μž¬ 검사쀑인 κ°’)으둜 μ£Όμ‹μˆ˜μ΅μ˜ μ΄ν•©μœΌλ‘œ λ”ν•΄μ£Όμ—ˆλ‹€.

μ΄λŸ°μ‹μœΌλ‘œ μ‹œκ°„λ³΅μž‘λ„λ₯Ό O(N^2)μ—μ„œ O(N) ν˜•μ‹μœΌλ‘œ λ°”κΎΈκ²Œλ˜λ‹ˆ 문제λ₯Ό ν•΄κ²° ν•  수 μžˆμ—ˆλ‹€.

code

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

int		main(void)
{
	int t, n;
	long long m, temp, max;
	std::vector <long long> v;

	std::cin >> t;
	for(int i = 0; i < t; i++)
	{
		std::cin >> n;
		for(int j = 0; j < n; j++) {
			std::cin >> temp;
			v.push_back(temp);
		}
		m = 0;
		max = 0;
		for (int k = v.size() - 1; k >= 0; k--) {
			if (v[k] > max) max = v[k];
			else if (v[k] < max) m += max - v[k];
		}
		std::cout << m << "\n";
		v.clear();
	}

	return (0);
}


ν›„κΈ°

μ‹œκ°„λ³΅μž‘λ„λ₯Ό 미리 계산을 해보고 섀계λ₯Ό μ œλŒ€λ‘œ μ„Έμ›Œμ„œ λ¬Έμ œμ— 접근을 ν–ˆμœΌλ©΄ μ‹œκ°„μ΄ˆκ³Όλ₯Ό μ €λ ‡κ²Œ 많이 λ‚΄μ§€μ•Šκ³  λΉ λ₯΄κ²Œ λ¬Έμ œμ— μ ‘κ·Ό ν•  수 μžˆμ—ˆμ„ κ±° 같은데 아직 μ‹œκ°„λ³΅μž‘λ„λ₯Ό κ³„μ‚°ν•˜λŠ”κ²ƒλ„ μ„€κ³„ν•˜λŠ” 뢀뢄에 μžˆμ–΄μ„œ 많이 λΆ€μ‘±ν•˜λ‹€κ³  느끼게 λ˜μ—ˆλ‹€.

λ”μš± λ‹€μ–‘ν•œ λ¬Έμ œλ“€μ˜ 접근을 ν•΄λ΄μ„œ λΉ λ₯΄κ²Œ 효율적인 λ‘œμ§μ„ 섀계할 수 μžˆλ„λ‘ λ…Έλ ₯을 ν•΄μ•Όν•  κ±° κ°™λ‹€.