기본 콘텐츠로 건너뛰기

11066 : 파일 합치기 (Dynamic Programming) [C,C++]

DP 문제는 DP 문제인 줄 알아도 적용을 잘 못하겠다..


더 많이 풀어봐야겠다.


A4용지 4장을 끄적이다 결국 구글링 찬스를 사용했다!


최소 행렬 곱셈 문제와 유사한 문제


앞부터 뒤까지 하나 하나 다해보고 그것 중의 최솟값을 구하는 문제이다.


최소 행렬 곱셈의 식은 DP[i][j] = min(DP[i][j], DP[i][k] + DP[k+1][j] + d(i-1) * d(k) * d(j))


파일 합치기 식은 DP[i][j] = min(DP[i][j], DP[i][k] + DP[k+1][j] + sum[i][j]

왜 최소 행렬 곱셈과 비슷하냐면 파일 합치기 문제는 앞과 뒤만 비교하고


교환법칙이 성립하지 않는다.



for (int i = 0; i <= Size; i++)
{
 for (int n = 1; n <= Size; n++)
 {
  int m = n + i;

  if (n == m || m > Size)
   continue;

  DP[n][m] = INT_MAX;

  for (int k = n; k < m; k++)
   DP[n][m] = min(DP[n][m], DP[n][k] + DP[k + 1][m] + Sum[m] - Sum[n - 1]);
 }
}
<소스 코드>




*Source of the problem = https://www.acmicpc.net/problem/11066
*문제 출처 : BAEKJOON ONLINE JUDGE

댓글

이 블로그의 인기 게시물

11004 : K번째 수 [C++]

# include < iostream > # include < cstdio > # include < algorithm > int main ( ) { int * Number = new int [ 5000000 ] ; int N , K ; scanf ( " %d %d " , & N , & K ) ; for ( int i = 0 ; i < N ; i + + ) scanf ( " %d " , Number [ i ] ) ; std :: sort ( Number , Number + N ) ; printf ( " %d " , Number [ K - 1 ] ) ; return 0 ; }

1149 : RGB Street Coloring (Dynamic Programming) [C,C++]

The key to this problem lies in understanding the principles. Let me explain the algorithm to solve the problem by using DP. First, you need the same storage space like input data's size. When you draw any color of the nth house, the space will contain the minimum value. If you paint the red in the second house, this value is sum of blue or green of the first house.  You must use DP because you must use the previous value.  Of course, you can also use the recursive algorithm to solve it. But if it gets bigger, it will take a lot of time.  If you paint the red in the nth house in the same way, you should add the lower value of the blue and green of the n-1th house.  Therefore, the minimum value can be found in the value of the storage space (n-1) index. <pesudo code> *Source of the problem =  https://www.acmicpc.net/problem/1149 *문제 출처 : BAEKJOON ONLINE JUDGE

11478 : 서로 다른 부분 문자열의 개수 (미제) [C++]

# include < iostream > # include < vector > # include < string > using namespace std ; int main ( ) { string sInput ; getline ( cin , sInput , '\n' ) ; int Time = 1 ; int Count = 0 ; vector < string > Storage ; for ( int i = 0 ; i < sInput . size ( ) ; i + + ) { for ( int j = 0 ; ( j + Time - 1 ) < sInput . size ( ) ; j + + ) Storage . push_back ( sInput . substr ( j , Time ) ) ; Time + + ; } bool * Visited = new bool [ Storage . size ( ) * sizeof ( bool ) ] ; for ( int i = 0 ; i < Storage . size ( ) ; i + + ) { Visited [ i ] = true ; for ( int j = 0 ; j < Storage . size ( ) ; j + + ) { if ( i ! = j & & Storage [ i ] = = Storage [ j ] ) { Visited [ i ] = false ; Visited [ j ] = true ; break ; } } } for ( int i = 0 ; i < Storage . size ( ) ; i + + ) if ( Visited [ i ] ) Count ...