https://www.acmicpc.net/problem/1699
1부터 N까지 모두 제곱수의 합으로 나타낼 수 있다.
모든 항목을 1의 제곱수의 합으로 채운다면 숫자의 크기가 곧 경우의 수가 될 것이다.
먼저 dp[i]는 i를 제곱수의 합으로 나타내는 경우라고 할 때
1로만 더해서 i값을 만든다면 경우의 수는 i가 될 것이다.
그리고 1부터 시작해서 어떤 수를 제곱했을 때 i에 가장 가까운 수를 n이라고 했을 때
dp[i]=min(dp[i],dp[i-n*n]+1)로 나타낼 수 있다.
예를 들어, dp[5]의 경우
dp[5]=dp[5-1*1]+1 (dp[4]인 경우에 1을 제곱한 값을 더한 경우)
dp[5]=dp[5-2*2]+1 (dp[1]인 경우에 2를 제곱한 값을 더한 경우)
...
로 나타낼 수 있다.
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 | #include <iostream> #include <algorithm> #include <vector> using namespace std; int main() { int N; cin>>N; vector<int> dp(N+1,0); for(int i=1;i<=N;i++){ dp[i]=i; for(int j=1;j*j<=i;j++) dp[i]=min(dp[i],dp[i-j*j]+1); } cout<<dp[N]<<endl; return 0; } | cs |
'알고리즘(BOJ) > DP' 카테고리의 다른 글
백준 1965번 - 상자넣기 (0) | 2018.02.10 |
---|---|
백준 11055번 - 가장 큰 증가 부분 수열 (0) | 2018.02.02 |
백준 2133번 - 타일 채우기 (4) | 2018.01.29 |
백준 11048번 - 이동하기 (0) | 2018.01.28 |
백준 11057번 - 오르막 수 (0) | 2018.01.28 |