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

C++의 주어진 문자열에서 k개의 고유한 부분 시퀀스를 찾은 후 비용을 찾는 프로그램

<시간/>

문자열 s와 다른 값 k가 있다고 가정합니다. k개의 고유한 하위 시퀀스를 얻을 수 있도록 s의 일부 하위 시퀀스를 선택해야 합니다. 여기서 부분 시퀀스를 선택하는 비용은 (s)의 길이 - (부분 시퀀스)의 길이와 같습니다. 따라서 k개의 고유한 하위 시퀀스를 선택한 후 가능한 가장 낮은 총 비용을 찾아야 합니다. 이 집합을 찾을 수 없으면 -1을 반환합니다. 빈 문자열을 유효한 하위 시퀀스로 간주합니다.

따라서 입력이 s ="pqrs", k =4와 같으면 출력은 3이 됩니다.

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

  • n :=s

    의 크기
  • (n + 1) x (n + 1) 크기의 2차원 배열 dp 하나를 정의하고 0으로 초기화

  • 마지막으로 하나의 지도 정의

  • dp[0, 0] :=1

  • initialize i :=0의 경우, i

    • dp[i + 1, 0] :=1

    • j를 초기화하기 위해 :=(i + 1), j>=1일 때 업데이트(j를 1만큼 감소), −

      • dp[i + 1, j] :=dp[i, j] + dp[i, j - 1]

    • s[i]가 last의 끝 요소가 아니면 -

      • j 초기화의 경우:=0, j <=last[s[i]]일 때 업데이트(j를 1만큼 증가), −

        • dp[i + 1, j + 1] - =dp[마지막[s[i]], j]

    • 마지막[s[i]] :=i

  • 비용 :=0

  • 초기화 i :=n의 경우 i>=0일 때 업데이트(i를 1만큼 감소), −

    • val :=k 및 dp[n, i]

      의 최소값
    • 비용 :=비용 + (val * (n - i))

    • k :=k - dp[n, i]

    • k <=0이면 -

      • 루프에서 나오세요

  • k <=0이면 -

    • 반품 비용

  • 반환 -1

예시

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

#include <bits/stdc++.h>
using namespace std;
int solve(string s, int k) {
   int n = s.size();
   vector<vector<int>> dp(n + 1, vector<int>(n + 1, 0));
   unordered_map<char, int> last;
   dp[0][0] = 1;
   for (int i = 0; i < n; i++) {
      dp[i + 1][0] = 1;
      for (int j = (i + 1); j >= 1; j--) {
         dp[i + 1][j] = dp[i][j] + dp[i][j - 1];
      }
      if (last.find(s[i]) != last.end()) {
         for (int j = 0; j <= last[s[i]]; j++) {
            dp[i + 1][j + 1] -= dp[last[s[i]]][j];
         }
      }
      last[s[i]] = i;
   }
   int cost = 0;
   for (int i = n; i >= 0; i--) {
      int val = min(k, dp[n][i]);
      cost += (val * (n - i));
      k -= dp[n][i];
      if (k <= 0) {
         break;
      }
   }
   if (k <= 0) {
      return cost;
   }
   return -1;
}
int main(){
   cout << solve("pqrs",4) << endl;
   return 0;
}

입력:

"pqrs", 4

출력

3