제민
DP(4) - 카드 구매하기, 오르막 수, 스티커 본문
https://www.acmicpc.net/problem/11052
11052번: 카드 구매하기
첫째 줄에 민규가 구매하려고 하는 카드의 개수 N이 주어진다. (1 ≤ N ≤ 1,000) 둘째 줄에는 Pi가 P1부터 PN까지 순서대로 주어진다. (1 ≤ Pi ≤ 10,000)
www.acmicpc.net
D[n]을 카드 n개를 구매하기 위해 지불해야 하는 최댓값으로 지정했는데 그 뒤로 어떻게 해야 할지 모르겠었다.
D[n]의 초기값은 입력한 값임
D[2] = D[1]+D[1] or D[1];
D[3] = D[1]+D[2] or D[3];
D[4] = D[1]+D[3] or D[2]+D[2] or D[3]+D[1] or D[4];
테이블 설정만 해놓고 막막했는데 이렇게 아래서부터 천천히 올라가면 D[4]=D[1]+D[1]+D[1]+D[1] 이런 식으로 바꿀 필요가 없이 D 두 개의 합으로 나타낼 수 있다.
#include <bits/stdc++.h>
using namespace std;
int d[1005]; //D[n] 카드 n개를 구매하기 위해 지불해야 하는 최댓값
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
int n; cin>>n;
for(int i=1;i<=n;i++) cin>>d[i];
for(int i=1;i<=n;i++){
for(int j=1;j<i;j++){
d[i]=max(d[i-j]+d[j],d[i]);
}
}
cout<<d[n];
return 0;
}
https://www.acmicpc.net/problem/11057
11057번: 오르막 수
오르막 수는 수의 자리가 오름차순을 이루는 수를 말한다. 이때, 인접한 수가 같아도 오름차순으로 친다. 예를 들어, 2234와 3678, 11119는 오르막 수이지만, 2232, 3676, 91111은 오르막 수가 아니다. 수
www.acmicpc.net
D[i][j] 길이 i에 j로 끝나는 오르막 수의 수
D[1][0~9] = {1,1,1,1,1,1,1,1,1,1}
D[2][0~9] = {1,2,3,4,5,6,7,8,9,10}
D[3] 부터는 머리속으로 생각하기 복잡해진다.
규칙을 찾아보자.
D[3][0] = D[2][0]
D[3][1] = D[3][0] + D[2][1]
D[3][2] = D[3][0] + D[2][1] + D[2][2]...
규칙을 찾았다.
D[i][j] = D[i][j-1] + D[i-1][j]
#include <bits/stdc++.h>
using namespace std;
int d[1003][10];
int main(){
ios::sync_with_stdio(0); cin.tie(0);
int n; cin>>n;
for(int i=1;i<=n;i++){
d[i][0]=1;
for(int j=1;j<=9;j++){
d[i][j]=d[i][j-1]+d[i-1][j];
d[i][j]%=10007;
}
}
cout<<accumulate(d[n],d[n]+10,0)%10007;
return 0;
}
accumulate는 누적합을 구하는 함수이고, 두 번째 인자는 미만인 값이다.
https://www.acmicpc.net/problem/9465
9465번: 스티커
첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스의 첫째 줄에는 n (1 ≤ n ≤ 100,000)이 주어진다. 다음 두 줄에는 n개의 정수가 주어지며, 각 정수는 그 위치에 해당하는 스티커의
www.acmicpc.net
DP... 정말 쉽지 않다.
#include <bits/stdc++.h>
using namespace std;
int d[5][100003], a[5][100003];
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int t; cin>>t;
while(t--){
int n; cin>>n;
for(int i=1;i<=2;i++)
for(int j=1;j<=n;j++)
cin>>a[i][j];
d[1][1]=a[1][1]; d[2][1]=a[2][1];
d[1][2]=a[1][2]+d[2][1];
d[2][2]=a[2][2]+d[1][1];
for(int i=3;i<=n;i++){
d[1][i]=a[1][i]+max(d[2][i-2],d[2][i-1]);
d[2][i]=a[2][i]+max(d[1][i-2],d[1][i-1]);
}
cout<<max(d[1][n],d[2][n])<<'\n';
}
return 0;
}
'코테연습일지 > DP' 카테고리의 다른 글
9084 2293 2294 동전 (0) | 2024.02.18 |
---|---|
DP [Knapsack](1) - 평범한 배낭, 앱, 안녕, 최대 페이지 수, 양팔저울 (0) | 2024.02.16 |
DP(3) - 부분 수열, 퇴사, 쉬운 계단 수 (0) | 2024.02.15 |
DP(2) - 피보나치 함수, 정수 삼각형, 이친수 등... (0) | 2024.02.14 |
DP(1) - 연습문제 풀기 (1) | 2024.02.14 |