import sys
import heapq

input = sys.stdin.readline


N, K = map(int,input().split())

visited = [False]*K
jewel = []
for _ in range(N):
    m,v = map(int,input().split())
    heapq.heappush(jewel,(m,v))

bags = []
for _ in range(K):
    bags.append(int(input()))

bags.sort()
result = 0
possible_jewel = []
for bag in bags:
    while jewel and jewel[0][0] <= bag:
        m,v = heapq.heappop(jewel)
        heapq.heappush(possible_jewel,-v)
    
    if possible_jewel:
        result -= heapq.heappop(possible_jewel)
        
    

print(result)

 

N, M = map(int,input().split())
total_length = N*M
so_list = [M]*N

cnt = 0
for k in range(N):
    if so_list[k]%N:
        cnt += so_list[k]//N
    else:
        cnt = cnt + so_list[k]//N-1
    so_list[k] -= so_list[k]//N*N

if sum(so_list):
    ind = 0
    temp = 0
    while ind <N:
        temp += so_list[ind]
        if temp == N:
            temp = 0
        elif temp >N:
            cnt += 1
            temp -= N
        ind += 1
        
print(cnt)

 

 

import functools
n,m = map(int,input().split())
@functools.lru_cache()
def gdc(n,m):
    if not n%m:
        return m
    return gdc(m,n%m)

print(m-gdc(n,m))
def solution(ind,diff):
    if diff > 250000:
        return -INF
    if ind == N:
        if diff == 0:
            return 0
        else:
            return -INF
    if dp[ind][diff] != -1:
        return dp[ind][diff]

    dp[ind][diff] = solution(ind+1,diff+arr[ind])
    dp[ind][diff] = max(dp[ind][diff],solution(ind+1,diff))
    if arr[ind] > diff:
        dp[ind][diff] = max(dp[ind][diff],diff + solution(ind+1,arr[ind]-diff))
    else:
        dp[ind][diff] = max(dp[ind][diff],arr[ind] + solution(ind+1,diff-arr[ind]))
    return dp[ind][diff]

N = int(input())
arr = list(map(int,input().split()))
arr = arr + [0]
INF = float('inf')
dp = [[-1] * 500001 for _ in range(N+1)]

result = solution(0,0)
if result == 0:
    print(-1)
else:
    print(result)

 

힘들게 풀었던 문제이다.

 

dp의 테이블에서 행은 현재의 index를 말하며, 열은 두 탑의 격차의 절대값을 말한다.

 

재귀함수를 통해 짰는데.

 

첫번째 : 해당 블록을 높이가 더 높은 쪽에 놓았을때,

 

두번째 : 해당 블록을 놓지 않았을때

 

세번째 : 높이가 낮은 블록에 놓았을 때 : 이 때 주의해야할 것은 현재 공통적으로 쌓아올려진 높이는 diff와 arr[ind]의 두 크기 중 작은 것에 된다.

 

이렇게 3가지 경우로 나뉘며, 세번째에는 격차가 클때와 현재 블록이 클때로 나뉘어서 된다.

 

 

이렇게 재귀를 하면서 마지막에서 들어온 diff가 0이면 높이가 같은것이므로 0을 반환해주고, 그게 아니면 두 높이가 다른것이므로, -INF를 반환해준다.

 

 

이게 내 첫번째 풀이였고, 실행시간은 3900ms로 엄청 느렸다.

 

그래서 다른 사람 풀이를 보고 공부한 코드는 다음과 같다.

import sys
input = sys.stdin.readline

N = int(input())
arr = list(map(int,input().split()))

if N == 1:
    print(-1)
else:
    total_sum = sum(arr)
    dp = [[-1] * total_sum for _ in range(N)]
    dp[0][0] = 0
    dp[0][arr[0]] = arr[0]
    for ind in range(N-1):
        for j in range(total_sum//2+1):
            if dp[ind][j] != -1:
                # 다음 거의 블록을 쓰지 않을때
                dp[ind+1][j] = max(dp[ind][j],dp[ind+1][j])
                # 두 탑 중 더 높은 탑쪽에 블록을 쌓을때
                if j + arr[ind+1] < total_sum:
                    dp[ind+1][j+arr[ind+1]] = max(dp[ind+1][j+arr[ind+1]],dp[ind][j]+arr[ind+1])
                # 더 낮은 탑 쪽에 쌓는데 새로 쌓는 블록이 기존 블록보다 높을때 와 아닐때
                if arr[ind+1] > j:
                    dp[ind+1][arr[ind+1]-j] = max(dp[ind+1][arr[ind+1]-j],dp[ind][j] + arr[ind+1]-j)
                else:
                    dp[ind+1][j-arr[ind+1]] = max(dp[ind+1][j-arr[ind+1]],dp[ind][j])
    if dp[-1][0] == 0:
        print(-1)
    else:
        print(dp[-1][0])

 

 

위와 dp 테이블은 동일하다. 그런데 전체 input의 합을 구하고, 그거의 반만큼만 반복을 돌리도록 했다.

 

그래서 위에서는 재귀를 통해서 돌아가다 보니, 무조건 3개의 함수가 실행되다보니 밑의 코드보다 훨씬 오래걸린다.

 

밑의 코드는 50*250000이 최대 횟수로 볼수 있으므로, 위의 것보다 연산량에 이득을 본것 같다.

 

여기도 위와 비슷하게,

 

아무것도 놓지 않았을때

두 탑 중 더 높은 탑쪽에 쌓았을때,

두 탑 중 더 낮은 탑쪽에 쌓았을때,

 

를 구분해서 놓으면 된다.

 

그리고 dp에 저장되는 값은 해당 index에서 두 탑의 높이가 diff만큼 차이가 날때, 그때 더 높은탑의 크기를 저장해놓는 것이므로,

 

그것을 잘 구분해서, dp에 저장시켜주면 된다.

'알고리즘 > 백준' 카테고리의 다른 글

[BOJ/백준] 1194 달이 차오른다 가자  (0) 2021.05.11
[BOJ/백준] 2933 미네랄  (0) 2021.05.10
[BOJ/백준] 1071 소트  (0) 2021.05.02
[BOJ/백준] 1062 가르침  (0) 2021.05.02
[BOJ/백준] 1976 여행 가자  (0) 2021.04.08
N = int(input())
arr = list(map(int,input().split()))

num_cnt = [0]*1005

for num in arr:
    num_cnt[num] += 1


cur = 0
result = []
while sum(num_cnt)>0:
    if num_cnt[cur]:
        if num_cnt[cur+1]:
            for next_num in range(cur+2,1001):
                if num_cnt[next_num]:
                    result.extend(num_cnt[cur]*[cur])
                    result.append(next_num)
                    num_cnt[cur] = 0
                    num_cnt[next_num] -= 1
                    break
            else:
                result.extend(num_cnt[cur+1]*[cur+1])
                result.extend(num_cnt[cur]*[cur])
                num_cnt[cur] = 0
                num_cnt[cur+1] = 0

        else:
            while num_cnt[cur]:
                result.append(cur)
                num_cnt[cur] -= 1
    cur += 1

print(*result)

 

플래티넘 문제로 어려웠던 문제였다. 

 

이 문제를 푸는 방법은 구분을 하는 것이다.

 

현재 숫자를 CUR이라고 하겠다. CUR+1의 숫자가 있는 경우와 없을때를 비교를 해서, 정렬을 해주면된다.

 

만약 CUR + 1의 숫자가 없을때에는 CUR의 값을 전부 출력시키면 된다.

 

 

그러나 CUR+1의 값이 존재할때는 2가지 경우가 있다.

 

CUR 보다 2이상 큰 값들이 존재하는지와 없는지 이다.

 

만약 없을때에는 CUR+1의 값들을 전부 출력한뒤에 CUR 값들을 출력시키면 된다.

 

그게 아니라 CUR보다 2이상 큰 값이 존재를 한다면,

 

CUR의 값들을 전부 출력시키고 그 다음에 CUR보다 2이상 큰 값을 한개 출력해주면 된다.

 

그러면 CUR과 CUR+1 사이에 CUR+2(이상)의 값이 들어가줘서 문제의 조건대로 출력이 가능해진다.

 

 

'알고리즘 > 백준' 카테고리의 다른 글

[BOJ/백준] 2933 미네랄  (0) 2021.05.10
[BOJ/백준] 1126 같은 탑  (0) 2021.05.02
[BOJ/백준] 1062 가르침  (0) 2021.05.02
[BOJ/백준] 1976 여행 가자  (0) 2021.04.08
[BOJ/백준] 7576 토마토  (0) 2021.04.08
from itertools import combinations

N,K = map(int,input().split())
ord_dict = {}
if K <5:
    print(0)
    exit()
elif K == 26:
    print(N)
    exit()
else:
    # 2**승으로 만들어 주기 위한 곳
    for k in range(26):
        ord_dict[chr(k+97)] = k

    K = K - 5
    comb_bits = 0
    # 무조건 있는 애들을 기본적으로 comb_bits로 만들어준다.
    for k in ['a','n','t','i','c']:
        comb_bits = comb_bits + 2**ord_dict[k]
    word_list = []


    for _ in range(N):
        # 앞뒤 고정 부분은 필요없으니 자른다.
        temp = set(list(input())[4:-4])
        word_list.append(temp)
    # 고정적으로 잇는 부분 제외하고 나머지를 뽑는다.
    combi_word = set(ord_dict.keys()) - set(['a','n','t','i','c'])
    result = 0
    for pick_words in combinations(combi_word,K):
        check_bits = comb_bits
        for pick_word in pick_words:
            # OR 연산을 해줘서 BIT 형식으로 만들어준다.
            check_bits = check_bits | 1<< ord_dict[pick_word]

        word_cnt = 0
        for word in word_list:
            for wo in word:
                # 만약에 AND 연산을 했는데 False가 나오면 그만둔다.
                if not (check_bits & 1<<ord_dict[wo]):
                    break
            else:
                word_cnt += 1
        result = max(word_cnt,result)
                
    print(result)

 

 

어렵지 않은 문제인데 python을 이용해서 풀려면 참 난감해진 문제였다. 조합을 잘 짜면, 시간을 넘지않을수도 있지만, 

 

시간초과에 걸리는 경우가 많았다.

 

그래서 조합을 구하는 방식을 비트마스킹을 통해 만들었따. 2**(k)승의 형태로 만들어주고, and 연산을 해서 우리가 만든 조합에 포함되어있는지 아닌지 확인하는 방식이다.

 

from itertools import combinations

N,K = map(int,input().split())
ord_dict = {}

for k in range(26):
    ord_dict[chr(k+97)] = k

K = K - 5
if K <0:
    print(0)
    exit(0)
else:
    origin_word = set(['a','n','t','i','c'])
    word_bit_list = list()
    combination_word = set()
    answer = 0
    for _ in range(N):
        temp = set(list(input())[4:-4]) - origin_word
        if len(temp) == 0:
            answer += 1
        elif len(temp) <=K:
            word_bit = 0
            for w in temp:
                word_bit = word_bit + 2**ord_dict[w]
            word_bit_list.append(word_bit)
            combination_word |= temp

    word_lens = len(combination_word)
    if K > word_lens:
        K = word_lens
    chk_cnt = 0
    for pick_words in combinations(combination_word,K):
        cnt = 0
        temp = 0
        for pick_word in pick_words:
            temp = temp + 2**ord_dict[pick_word]
        for word_bit in word_bit_list:
            if word_bit & temp == word_bit:
                cnt += 1

        chk_cnt = max(chk_cnt,cnt)

    print(answer + chk_cnt)

위의 방식보다 훨씬 빠른 방식이다. 이 방식은 기본적인 컨셉은 비슷하다.

 

하지만 2가지가 다르다.

 

첫번째는 전체 알파벳 26개중에서 K개를 뽑던거에서 고정적으로 들어간 a,c,i,n,t를 무조건 뽑는다고 생각하고,

 

그리고 주어진 단어들에 있는 단어들 중에서 나머지 K-5개를 뽑는것이다.

 

 

두번째는 각 단어들의 BIT를 비교했던것에서 단어 전체의 bit를 저장해준뒤, 우리가 만든 combination bit와 and 연산을해서, 원래 word_bit가 유지되는지 확인을 해주는 방식이다.

 

이러한 방법을 통해 시간을 줄일 수 있다.

'알고리즘 > 백준' 카테고리의 다른 글

[BOJ/백준] 1126 같은 탑  (0) 2021.05.02
[BOJ/백준] 1071 소트  (0) 2021.05.02
[BOJ/백준] 1976 여행 가자  (0) 2021.04.08
[BOJ/백준] 7576 토마토  (0) 2021.04.08
[BOJ/백준] 2812 크게 만들기  (0) 2021.04.08

어제 결국 플레 5를 달성했다..

 

플레4는 그냥 꿈만 꾸는걸로

'주절주절' 카테고리의 다른 글

[BOJ/백준] 플레3 달성?  (0) 2021.11.09
글이 뜸한 이유  (0) 2021.08.20
[백준/BOJ] 플레4 달성  (0) 2021.06.05
백준 골드1 달성  (0) 2021.03.11
백준 150문제 돌파.  (0) 2021.02.18

운영체제 : 02 운영체제의 개념과 구조

  • Comupter System

    • the hardware
    • the operating system
    • the application programs
    • user

운영체제의 정의

  • There are No universally accepted definition of an operating system
  • A more common definition is that
    • the one program running at all times on the computer
      • 운영체제는 컴퓨터에서 항상 돌아가는 프로그램이라고 정의한다.
    • usallay called the kernel
  • kerneal에서 제공하는 프로그램
    • system programs
    • application programs

컴퓨터의 기본적인 구조 (classical computer system)

  • one or more CPUs and
  • a number of device controllers connected through a common bus

부트스트랩 프로그램 (bootstrap program)

  • 컴퓨터가 켜졌을때 가장 처음에 실행되어야하는 프로그램
    • 운영체제를 로딩하는 일
    • 하드에 있는 운영체제를 메모리에 로딩해주는 일

인터럽트 (Interrupts)

  • I/O device가 CPU에 신호를 보내는 트리거
  • Hardware may trigger an intterupt at any time
    • 시스템 버스를 통해, 시그널을 CPU에 보낸다.

폰 노이만 아키텍쳐

  • 산술 논리 장치와 프로세서 레지스터를 포함하는 처리 장치
  • 명령 레지스터와 프로그램 카운터를 포함하는 컨트롤 유닛
  • 데이터와 명령어를 저장하는 메모리
  • 외부 대용량 스토리지
  • 입출력 매커니즘
  • A typical instruction - execution cycle
    • first fetches an instruction from memory
    • and stores that instruction in instruction register
      • 명령어 레지스터가 있어서, 명령어를 fetch를 하고 execute를 해주는 방식을 폰 노이만 구조라 한다.
  • The instruction is the decoded
    • and may cause operands to be fetched from memory
    • and stored in some internal register
  • After the instruction on the operands
    • has been executed
    • the result may be stored back in memory
  • Storage System의 계층 구조

    • register : CPU 내에 있는 저장장치
    • cache : register와 main memory사이에 있다. 메모리보다 빠르다.
    • main memory : 우리가 흔히 말하는 램
    • solid - state dist : 메모리 형태의 하드디스크
    • hard dist : HDD
  • I/O Structure

  • DMA : Direct memory access
  • A large portion of OS code is dedicated to managing I/O
  • 컴퓨터 시스템 컴포넌트의 정의

    • CPU : The hardware that executes instructions
    • Processor : A physical chip that contains one or more CPUs
    • Core : The back computation unit of the CPU
    • MultiCore : Including multiple computing cores on the same CPU
  • Symmetric multiprocessing(SMP)

  • 둘 이상의 동일한 프로세서가 단일 공유 주 메모리 에 연결되고 모든 I / O 장치에 대한 전체 액세스 권한을 가지며 처리하는 단일 운영 체제 인스턴스에 의해 제어되는 다중 프로세서 컴퓨터 하드웨어 및 소프트웨어 아키텍처
  • Multi Core design

    • 같은 프로세서에 여러개의 core로 나눈게 멀티 코어 디자인이다.

  • multiprogramming
    • 여러개의 프로그램을 동시에 메모리에 올려놓고 실행하는 것
    • keeps several proccesses in memory simulaneously
    • to increase CPU utilization( CPU의 사용율을 높여줌)
  • Multitasking(멀티프로세싱) : concurrency(pallerelism과 차이를 알아야한다.)
    • a logical extension of multiprogramming
      • CPU가 여러개의 작업을 자주 바꾸면서 여러개의 프로그램을 동시에 돌아가는 것처럼 사용자가 느낄수 있게 된다.
    • CPU scheduling : (CPU 스케쥴링이 중요)
      • 만약에 같은 시간에 여러개의 프로세스가 실행이 되었을때, 시스템은 무조건 그 프로세스 중에서 다음에 실행될것을 결정해줘야한다.
  • Two separate mode of operations

    • user mode and kernel mode

    • 프로그램의 잘못된 행동을 예방해주기 위해, 커널모드와 유저모드가 있다.

    • 그러므로, 컴퓨터에 직접적인 제어는 커널모드에서만 가능하고, 유저모드에서는 동작이 불가능하게 했다.

  • Virtualization (가상화)
    • technology that allow us
      • to abstract the hardware of single computer
      • into several diffrent execution enviroments
      • 한 컴퓨터에서 다양한 OS를 실행
  • OS의 제공하는 환경

    • User interface
    • Program execution
    • I/O operation
    • File system manipulation
    • Communications
    • Error detection
    • Resource allocation
    • Logging
    • Protection and security

  • System call

    • provide an interface to the services made available by the OS
    • API : Application Programming Interface
  • 2강 후기
    • 기초적인 컴퓨터에서 쓰이는 용어들에 대해 배웠다. 하지만 비 전공자라 그런지 모든 용어들이 새로워 이해하는데 시간이 걸렸다.

'기술공부 > OS' 카테고리의 다른 글

운영체제 3강  (0) 2022.05.18
운영체제 2강 - 2(반효경)  (0) 2022.05.13
운영체제 2강( 반효경)  (0) 2022.05.12
운영체제 소개 1강 (반효경)  (0) 2022.05.05
1. 운영체제가 뭐길래 (운영체제 강의 : 주니온)  (0) 2021.04.21

컴퓨터 네트워킹 하향식 접근

Chapter 1 컴퓨터 네트워크와 인터넷

1.1 인터넷이란 무엇인가?

  1. 인터넷의 구성요소를 기술하는 방법 ( 인터넷을 구성하는 기본적인 하드웨워와 소프트웨어 요소를 기술)
  2. 분산 애플리케이션에 서비스를 제공하는 네트워킹 인프라 관점에서 인터넷을 기술하는 것

1.1.1 구성요소로 본 인터넷

  • 인터넷에 연결되는 모든 장치는 호스트 혹은 종단 시스템(end system) 이라 부른다.

  • 종단시스템은 통신 링크(Communication Link)와 패킷 스위치(packet switch)의 네트워크로 연결된다.

  • 통신링크 : 동충 케이블, 구리선 광 케이블, 라디오 스펙트럼 등을 포함한 다양한 물리매체

    • 각각의 링크들은 다양한 전송률을 이용하여, 데이터를 전송한다.
  • 한 종단시스템에서 다른 종단 시스템으로 보낼 데이터를 가지고 있을때, 그 데이터를 세그먼트로 나누고, 각 세그먼트에 헤더를 붙인다.

  • 이렇게 만들어진 정보 패키지를 패킷(packet)이라고 부른다.

  • 패킷을 목적지 종단 시스템으로 보내지고, 목적지에서 재 조립이 된다.

  • 패킷을 전달해주는 패킷 교환기는 라우터링크 계층 스위치가 있다.

    • 라우터 : 네트워크 코어에서 사용
    • 링크 계층 스위치 : 액세스 네트워크에서 사용
  • 종단 시스템은 *ISP(Internet Service Provider) *를 통해 인터넷에 접속한다.

    • ISP은 다양한 네트워크들이 있고, ISP 네트워크는 따로 관리되고, IP 프로토콜을 수행하며, 네이밍, 주소배정 방식을 따른다.
  • 인터넷의 구성요소들은 인터넷에서 정보 송수신을 제어하는 프로토콜을 수행하며, TCP, IP가 가장 유명한 프로토콜이다.

    • IP 프로토콜 : 라우터와 종단시스템 사이에서 송수신되는 패킷 포맷

1.1.2 서비스 측면에서 본 인터넷

애플리케이션에 서비스를 제공하는 인프라 구조로 인터넷을 기술한 방법

  • 서로 데이터를 교환하는 많은 종단 시스템을 포함하고 있는 애플리케이션을 분산 애플리케이션 이라고 부른다
    • 인터넷 애플리케이션들은 종단시스템에서만 수행된다. 즉, 패킷교환기에서는 수행이 되지 않는다.
    • 패킷교환기들은 종단시스템 간의 데이터 교환을 쉽게 해주지만, 이 애플리케이션이 무엇을 하는지 관심이 없다.
  • 소켓 인터페이스 : 인터넷에 접속된 종단시스템에서 한 종단시스템에서 다른 종단시스템에서 수행되는 특정 목적지 프로그램에게 데이터를 전달하도록 요구사항을 명시되어있는 것
    • 예를 들면, 우편 서비스를 이용을 할때, 봉투에 우편을 붙이고, 봉투에 편지를 넣은뒤, 그 봉투를 우체통에 넣는 이 과정을 우편 서비스 인터페이스라고 한다.
    • 즉, 송신프로그램이 데이터를 목적지 프로그램에 전달할수 있도록 따라야하는 과정이 소켓 인터페이스이다.

1.1.3 프로토콜이란 무엇인가?

​ 프로토콜은 둘 이상의 통신 개체 간에 교환되는 메시지 포맷과 순서 뿐 아니라, 메시지의 송수신과 다른 이벤트에 따른 행동들을 정의한다.

ex ) 혼잡제어(congestion - contral) 프로토콜 : 종단 시스템에서 송수신자 간의 전송되는 패킷률을 조절한다.

​ 라우터에서의 프로토콜 : 송신지에서 목적지까지 패킷의 경로를 설정한다.

+ Recent posts