일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- JPA
- 세그먼트 트리
- 이펙티브 자바
- dataframe
- series
- dfs
- DP
- disjoint set
- BFS
- 포트앤어댑터 아키텍처
- spring security
- 파이썬
- 데이터 flow
- ddd
- 자바
- java
- springboot
- 비트마스크
- 스프링
- UML
- docker
- 다익스트라
- 문자열
- 위상정렬
- pandas
- Redis
- equals
- 알고리즘
- 헥사고날 아키텍처
- 백준
Archives
- Today
- Total
코딩못하는사람
1086 박성원 (비트,DP) 본문
https://www.acmicpc.net/problem/1086
1.접근
방문했던곳들의 상태를 표기하기 쉽도록 비트마스크를 사용하고 n이 15일때 15!로 숫자가 크므로
DP를 사용해줘야 한다.
2.풀이
분모를 N!,분자를 k로 나눠떨어지는 경우의 수로 두는 문제이다.그래서 나는 DP배열을
DP[방문한곳][현재 나머지]로 만들고 DP[방문한곳][현재 나머지]=방문할 수 있는 곳들에서의 경우의 수 합 으로 점화식을 만들었다.그렇게 DFS를 사용하여 방문했던 곳이 나오면 그대로 값을 리턴하고 만약 모든 곳을 방문하고 나머지가 0일 때는 1을 리턴해주는 함수DFS를 만들었다.
나머지는 (이번에 추가하는 숫자*10**현재수의 길이) 현재 나머지를 더하고 k로 나눠주면서 저장하면 된다.
DP를 0으로 초기화 해두면 이미 0으로 메모제이션 된곳도 착각할까봐 -1로 초기화 하였다.
3.코드
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
from math import gcd,factorial | |
input=sys.stdin.readline | |
def dfs(L,visit,rest): | |
if visit==(1<<n)-1: | |
if rest==0: | |
return 1 | |
else: | |
return 0 | |
if dp[visit][rest]!=-1: | |
return dp[visit][rest] | |
for i in range(n): | |
if visit&(1<<i)==0: | |
dp[visit][rest]+=dfs(L+long[i],visit|(1<<i),(rest+rm[i][L])%k) | |
dp[visit][rest]+=1 | |
return dp[visit][rest] | |
n=int(input()) | |
stack=[] | |
for _ in range(n): | |
stack.append(int(input())) | |
long=[] | |
for i in stack: | |
long.append(len(str(i))) | |
k=int(input()) | |
dp=[[-1]*k for _ in range(1<<n)] | |
rm = [[-1]*(sum(long)) for _ in range(n)] | |
for i in range(n): | |
for j in range(sum(long)): | |
rm[i][j] = (stack[i]*10**j)%k | |
temp=dfs(0,0,0) | |
F=factorial(n) | |
if temp==0: | |
print('0/1') | |
else: | |
v=gcd(F,dp[0][0]) | |
print('{}/{}'.format(temp//v,F//v)) |
4.배운점
- gcd와 팩토리얼을 구현했었는데 math모듈에 다 있었다.
- 나머지에 대한 개념이 확실하지 않다
- rm배열을 만들지 않아놓고 계속 계산을 했었는데 그 곳에서 시간초과가 계속 났다. 수가 너무 큰 계산이라서 시간을 오래 잡아 먹는 것 같다. 다음에는 수가 큰 계산이 반복되면 배열로 선언해 놔야겠다.
'백준 문제풀이(JAVA,Python)' 카테고리의 다른 글
18809 Gaaaaaaaaaarden (1) | 2020.09.22 |
---|---|
2887 행성터널 (1) | 2020.09.03 |
13913 숨바꼭질 4 (BFS 역추적) (1) | 2020.09.02 |
2263 트리의 순회, 5639 이진 검색 트리 (1) | 2020.08.28 |
1167 트리의 지름순 (1) | 2020.08.27 |