백준1699(파이썬) - 제곱수의 합
resilient
·2021. 5. 17. 21:46
728x90
반응형
https://www.acmicpc.net/problem/1699
1699번: 제곱수의 합
어떤 자연수 N은 그보다 작거나 같은 제곱수들의 합으로 나타낼 수 있다. 예를 들어 11=32+12+12(3개 항)이다. 이런 표현방법은 여러 가지가 될 수 있는데, 11의 경우 11=22+22+12+12+12(5개 항)도 가능하다
www.acmicpc.net
- 이 문제는 처음봤을 때는 그리디라고 생각해서 풀었다. (주석 처리 된 코드)
- 당연히 그리디가 아니다. 50같은 경우에는 5^2 +5^2 인데 그리디로는 5^2는 한번밖에 사용할 수 없다.
- 그래서 바로 DP 라고 판단했다.
- DP문제 같은 경우에는 다른 게시물에서도 언급했지만 무조건 일단 경우의 수를 다 적어보고 생각하는게 좋은거 같다.
- 시간초과 문제도 해결했다. for 문에 min이 들어가면 시간초과가 나길래 if문으로 작성하였다.
# dp문제이다. 제곱수 항의 최소 개수 # n일 경우 1부터 n까지의 수들을 사용할 때 각각의 경우의 개수를 넣어주면될꺼같다. import sys input = sys.stdin.readline n = int(input()) dp = [0 for _ in range(n+1)] for i in range(1,n+1): dp[i] = i for j in range(1,i): #제곱수가 i보다 커지면 break if(j**2)>i: break # 1을 제외하고 작은수들부터 제곱한 수를 지금 기준이 되는 수와 비교해서 하나라도 있으면 그 제곱수를 넣어주고 1을 더해준다. # 예를 들어 i =16 j =4 처럼 나누어떨이지는 수가있으면 dp[0] = 0 에 1을 더해서 1개로 만들어준다. # dp[i - 1], dp[i - 4], dp[i - 9], dp[i - 16]중 가장 작은 값은 0이고 여기에 1을 더한 값을 dp[i]에 넣어준다. if dp[i] > dp[i-j**2]+1: dp[i] = dp[i-j**2]+1 print(dp[n]) #그리디인줄알았지만 틀린코드.. """ ans = [] for i in range(1,int((n+1)**0.5)+1): ans.append(i**2) cnt = 0 ans.sort(reverse=True) for i in ans: cnt += n//i n = n%i print(cnt) """
반응형
'자료구조 & 알고리즘 > 백준(Baekjoon)' 카테고리의 다른 글
백준2110(파이썬) - 공유기 설치 (0) | 2021.05.19 |
---|---|
백준17298(파이썬) - 오큰수 (0) | 2021.05.18 |
백준2583(파이썬) - 영역 구하기 (0) | 2021.05.17 |
백준7562(파이썬) - 나이트의 이동 (0) | 2021.05.16 |
백준11727(파이썬) - 2 x n 타일링2 (0) | 2021.05.14 |