https://www.acmicpc.net/problem/2302
일단 문제를 어떻게 풀까 생각해보면 예시대로 4,7번이 고정좌석이라면
1~3번의 경우의수 * 5,6의 경우의수 * 8,9의 경우의수 가 답인걸 알수있다. 그럼 여기서 더 들어가서
1~3번의 경우의 수는 어떻게 구할수 있을까? 노가다 결과 피보나치수임을 깨달았다.
좌석이 1개일경우 경우의수는 1개, 2개는 2개, 3개는 3개, 4개는 5개, .....
여기까지 생각하면 다 푼거다.
# -*- encoding: cp949 -*- dp = [0 for i in xrange(41)] n=input() m=input() m_list=[input() for i in xrange(m)] dp[1] = 1 dp[2] = 2 for i in xrange(3,n+1): dp[i] = dp[i-1] + dp[i-2] answer = 1 before = 0 for i in xrange(m): if m_list[i]-before-1!=0: answer *= dp[m_list[i] - before - 1] before = m_list[i] if n-before!=0: answer *= dp[n - before] print answer
https://www.acmicpc.net/problem/2550
lis문제는 앞에 지겹도록 다뤄봤으니 설명은 따로 안적음.
# -*- encoding: cp949 -*- from bisect import bisect_left def lis(line): dp = [0 for i in xrange(10002)] fr = [0 for i in xrange(10003)] size = 0 for i in xrange(len(line)): h = bisect_left(dp[:size],line[i]) if h==size: size += 1 dp[h] = line[i] fr[dp[h]] = dp[h-1] if h else 0 i=dp[size-1] lis_list = [] while i: lis_list.insert(0,i) i = fr[i] return lis_list n=input() a=map(int,raw_input().split()) b=map(int,raw_input().split()) c = [[a.index(i)+1,b.index(i)+1] for i in xrange(1,n+1)] line = map(lambda x:x[1],sorted(c,key=lambda x:x[0])) l = lis(line) print len(l) z = sorted([b[i-1] for i in l]) for i in z: print i,
https://www.acmicpc.net/problem/2643
lis문제라고 감을 잡을 수 있다.
1. 색종이를 90도 돌리는것이 가능하므로 색종이들을 [짧은변,긴변] 형태로 놓은 후 긴변을 기준으로 첫번째 정렬, 짧은변 기준으로 두번째 정렬을 해준다.
2. O(N^2) LIS소스로 LIS를 구한다. 색종이가 최대 100개이기때문에 N^2의 시간복잡도로도 충분하다. 색종이가 1,3 1,3일경우 2개로 세줘야한다. LIS는 항상 1이라도 증가하는 형태인데 이건 <=로 해줘야 한다. 아래 소스보면 이해할듯.
# -*- encoding: cp949 -*- from bisect import bisect_left dp = [-1 for i in xrange(102)] def lis(s): if dp[s+1]!=-1: return dp[s+1] dp[s+1] = 0 for i in range(s+1,n): if s==-1 or a[s][0] <= a[i][0]: dp[s+1] = max(dp[s+1], lis(i)+1) return dp[s+1] n=input() a=[map(int,raw_input().split()) for i in xrange(n)] a = sorted([[min(i),max(i)] for i in a],key=lambda x:(x[1],x[0])) #print 'a =',a print lis(-1)
https://www.acmicpc.net/problem/2225
잘 생각해보자. 5를 숫자 4개로 만드는 방법을 구한다고 하자.
5를 만들려면 (0,5), (1,4), (2,3), (3,2), (4,1), (5,0)의 6가지가 있다. 이걸 구하려면
(0을 숫자 2개로 만드는방법+5를 숫자 2개로만드는방법) + (1을 2개로+4를 2개로) + (2를 2개로+3을 2개로) + ..... (5를 숫자 2개로 만드는방법 + 0을 숫자 2개로 만드는 방법) 의 총합이 5를 숫자 4개로 만드는 방법이다.
# -*- encoding: cp949 -*- dp = [[0 for i in xrange(202)] for j in xrange(202)] n,k=map(int,raw_input().split()) mod = 1000000000 for i in xrange(n+1): dp[1][i] = 1 for i in xrange(2,k+1): for j in xrange(n+1): dp[i][j] = (dp[i][j] + sum(dp[i-1][:j+1]))%mod print dp[k][n]%mod
'algorithm > problem solving' 카테고리의 다른 글
acmicpc.net 2011(DP), 2240(DP), 2666(DP), 2624(DP) (0) | 2016.11.11 |
---|---|
acmicpc.net 1480(배낭 문제, DP, 비트마스크), 5557(DP, 조합), 2630(분할 정복) (0) | 2016.11.09 |
acmicpc.net 10164(DP), 2568(LIS, DP), 11054(LIS, DP) (0) | 2016.11.04 |
acmicpc.net 1535(배낭 문제, DP), 1915(DP), 1562(비트마스크, DP) (0) | 2016.11.01 |
acmicpc.net 3878(볼록 껍질, 기하), 2254(볼록 껍질, 기하), 2166(기하) (0) | 2016.10.30 |