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

C++의 목표 합계


음이 아닌 정수 a1, a2, ..., an 및 또 다른 값, 즉 대상 S의 목록이 있다고 가정합니다. 이제 2개의 기호 + 및 -가 있습니다. . 각 정수에 대해 새 기호로 +와 - 중에서 하나를 선택해야 합니다. 정수의 합을 목표 값 S와 같게 하기 위해 기호를 할당하는 방법의 수를 찾아야 합니다. 따라서 숫자가 [1,1,1,1,1]이고 S =3이면 출력은 다음과 같습니다. 5, 조합은 – 1 + 1 + 1 + 1 + 1 =3, + 1 – 1 + 1 + 1 + 1 =3, + 1 + 1 – 1 + 1 + 1 =3, + 1 + 1 +이므로 1 – 1 + 1 =3, + 1 + 1 + 1 + 1 – 1 =3. 따라서 할당하는 방법은 5가지가 있습니다.

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

  • 크기가 21 x 2001인 하나의 테이블 dp를 만들고 여기에 - 1을 채웁니다. 이것은 동적 프로그래밍 접근 방식에 사용됩니다.
  • 재귀적 메서드는 solve()라는 이름으로 사용됩니다. 이것은 pos, 배열 v, tempSum 및 실제 합계 S를 취합니다. 이것은 아래와 같이 작동합니다 -
  • pos가 배열 v의 크기와 같으면 s =tempSum이면 true를 반환하고 그렇지 않으면 false를 반환합니다.
  • dp[pos, tempSum + 1000]이 -1이 아니면 dp[pos, tempSum + 1000]을 반환합니다.
  • ans :=solve(pos + 1, v, tempSum – v[pos], s) + solve(pos + 1, v, tempSum + v[pos], s)
  • dp[pos, tempSum + 1000] =ans
  • 반환
  • 매개변수 solve(0, nums, 0, s)를 사용하여 메인 섹션에서 solve() 호출

예(C++)

더 나은 이해를 위해 다음 구현을 살펴보겠습니다. −

#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
   int dp[21][2001];
   int solve(int pos, vector <int> v, int tempSum, int s){
      if(pos == v.size()){
         return s == tempSum;
      }
      if(dp[pos][tempSum+1000]!=-1)return dp[pos][tempSum+1000];
      int ans = solve(pos+1,v,tempSum-v[pos],s) +solve(pos+1,v,tempSum+v[pos],s);
      dp[pos][tempSum+1000] = ans;
      return ans;
   }
   int findTargetSumWays(vector<int>& nums, int s) {
      int n = nums.size();
      if(s>1000)return 0;
      for(int i =0;i<21;i++){
         for(int j =0;j<2001;j++){
            dp[i][j] = -1;
         }
      }
      return solve(0,nums,0,s);
   }
};
main(){
   Solution ob;
   vector<int> v = {1,1,1,1,1};
   cout << ob.findTargetSumWays(v, 3);
}

입력

[1,1,1,1,1]
3

출력

5