मान लीजिए कि हमारे पास गैर-ऋणात्मक पूर्णांकों की एक सूची है, 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. तो उन्हें असाइन करने के पाँच तरीके हैं।
इसे हल करने के लिए, हम इन चरणों का पालन करेंगे -
- 21 x 2001 आकार की एक टेबल डीपी बनाएं, इसे - 1 से भरें। इसका उपयोग गतिशील प्रोग्रामिंग दृष्टिकोण के लिए किया जाएगा
- पुनरावर्ती विधि का उपयोग किया जाएगा जिसे हल () कहा जाता है। यह pos, सरणी v, tempSum और वास्तविक योग S लेगा। यह नीचे की तरह कार्य करेगा -
- यदि pos सरणी v के आकार के समान है, तो सत्य लौटाएं, यदि s =tempSum, अन्यथा असत्य
- यदि dp[pos, tempSum + 1000] -1 नहीं है, तो dp[pos, tempSum + 1000] वापस करें।
- उत्तर :=हल करें(pos + 1, v, tempSum – v[pos], s) + हल करें (pos + 1, v, tempSum + v[pos], s)
- dp[pos, tempSum + 1000] =ans
- वापसी उत्तर
- पैरामीटर सॉल्व(0, nums, 0, s) का उपयोग करके मुख्य खंड से हल () को कॉल करें
उदाहरण(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