Computer >> 컴퓨터 >  >> 프로그램 작성 >> C++

C++에서 회문 하위 목록을 제거하는 데 필요한 작업 수를 찾는 프로그램

<시간/>

nums라는 숫자 목록이 있다고 가정합니다. 이제 회문인 일부 하위 목록을 삭제하는 작업을 고려해 보겠습니다. 목록이 비어 있도록 필요한 최소 작업 수를 찾아야 합니다.

따라서 입력이 nums =[6, 2, 4, 4, 2, 10, 6]과 같으면 출력은 2가 됩니다. 하위 목록 [2, 4, 4, 2]를 먼저 제거한 다음 목록은 [6, 10, 6]과 같습니다. 이것도 회문이므로 목록을 비우려면 제거하십시오.

이 문제를 해결하기 위해 다음 단계를 따릅니다. −

  • 105 x 105 크기의 배열 dp를 정의합니다.

  • dfs() 함수를 정의하면 i, j, 배열 v,

    가 필요합니다.
  • ret :=inf

  • i> j이면 -

    • 0 반환

  • i가 j와 같으면 -

    • 1 반환

  • j - i가 1과 같으면 -

    • return (v[i]가 v[j]와 같으면 1, 그렇지 않으면 2)

  • i + 1 <=j이고 v[i]가 v[i + 1]과 같으면 -

    • ret :=1 + dfs(i + 2, j, v)

  • dp[i, j]가 -1과 같지 않으면 -

    • 반환 dp[i, j]

  • ret :=(ret, 1 + (dfs(i + 1, j, v) 및 dfs(i, j - 1, v))의 최소값)

  • v[i]가 v[j]와 같으면 -

    • ret :=ret 및 dfs(i + 1, j - 1, v)의 최소값

  • k 초기화의 경우:=i + 2, k

    • v[i]가 v[k]와 같으면 &minnus;

      • ret :=ret 및 dfs((i + 1, k - 1, v) + dfs(k + 1, j, v))

        의 최소값
  • 반환 dp[i, j] =ret

  • 주요 방법에서 다음을 수행하십시오 -

  • dp를 -1로 채우기

  • n :=숫자 크기

  • 반환 dfs(0, n - 1, 숫자)

예시

이해를 돕기 위해 다음 구현을 살펴보겠습니다. −

#include <bits/stdc++.h>
using namespace std;
int dp[105][105];
int dfs(int i,int j, vector <int>& v){
   int ret= INT_MAX;
   if(i > j)
      return 0;
   if(i == j)
      return 1;
   if(j - i == 1){
      return v[i] == v[j] ? 1 : 2;
   }
   if(i + 1 <= j && v[i] == v[i + 1]){
      ret = 1 + dfs(i + 2, j, v);
   }
   if(dp[i][j] != -1) return dp[i][j];
      ret = min({ret, 1 + min(dfs(i + 1, j, v), dfs(i, j - 1, v))});
   if(v[i] == v[j]){
      ret = min(ret, dfs(i + 1, j - 1, v));
   }
   for(int k = i + 2; k < j; k++){
      if(v[i] == v[k]){
         ret = min(ret, dfs(i + 1, k - 1, v) + dfs(k + 1, j, v));
      }
   }
   return dp[i][j] = ret;
}
int solve(vector<int>& nums) {
   memset(dp , -1, sizeof dp);
   int n = nums.size();
   return dfs(0, n - 1, nums);
}
int main(){
   vector<int> v = {6, 2, 4, 4, 2, 10, 6};
   cout << solve(v);
}

입력

{6, 2, 4, 4, 2, 10, 6}

출력

2