C++ DP solution, I think pretty standard one.
Intuition\nI first thought of too brute method.\n\n# Approach\nWith sort of brute-force method I passed all but ~15 samples.\nWhen I realized I don\'t know how 
# Intuition\nI first thought of too brute method.\n\n# Approach\nWith sort of brute-force method I passed all but ~15 samples.\nWhen I realized I don\'t know how to improve it further, I tried to think of completely different approach (DP).\n\n# Complexity\n- Time complexity: did not evaluate.\n\n- Space complexity: O(n).\n\n# Code\n```\n#include <algorithm>\n#include <vector>\n#include <array>\n#include <set>\nusing namespace std;\n\n// 643/643 testcases passed, 1570ms, 42MB\n\n#define MAXNUM 20000\n#define MODULUS 1000000007\n\nstruct ValueAndCount\n{\n    int value;\n    int count;\n    int product;\n\n    ValueAndCount(int a_value, int a_count, int a_product) : value(a_value), count(a_count), product(a_product)\n    {\n    }\n\n    bool operator<(const ValueAndCount& o) const\n    {\n        int dproduct = product - o.product;\n        if (dproduct) return dproduct < 0; // azeby si\u0119 jak najwolniej rozje\u017Cd\u017Ca\u0142o\n        return value < o.value;\n    }\n};\n\nlong long sums[2][1 + MAXNUM];\nset<ValueAndCount> nextValueAndCount;\n\nclass Solution\n{\npublic:\n    static int countSubMultisets(vector<int>& a_nums, int a_lowSum, int a_highSum);\n};\n\nint Solution::countSubMultisets(vector<int>& a_nums, int a_lowSum, int a_highSum)\n{\n    std::sort(a_nums.begin(), a_nums.end(), [](int a, int b) {return a > b; });\n\n    nextValueAndCount.clear();\n    int thisValue = a_nums[0];\n    int thisIndex = 0;\n    int howManyLeft = 0;\n    int c, vc;\n    for (int curIndex = 1; curIndex < a_nums.size(); curIndex++)\n    {\n        if (a_nums[curIndex] != thisValue)\n        {\n            c = curIndex - thisIndex;\n            vc = thisValue * c;\n            nextValueAndCount.emplace(thisValue,c,vc);\n            howManyLeft += vc;\n            thisValue = a_nums[curIndex];\n            thisIndex = curIndex;\n        }\n    }\n    c = (int)a_nums.size() - thisIndex;\n    vc = thisValue * c;\n    nextValueAndCount.emplace(thisValue, c, vc);\n    howManyLeft += vc;\n\n    int currIdx = 0;\n    int prevIdx = 1;\n\n    sums[prevIdx][0] = 1;\n    int highSumAvail = 0;\n\n    for (const auto& valueAndCount : nextValueAndCount)\n    {\n        // warto\u015B\u0107 howManyLeft m\xF3wi o tym, ile jeszcze sumy maksymalnie mog\u0105 si\u0119 zwiekszy\u0107\n        // poniewa\u017C jeste\u015Bmy zainteresowani zakresem od a_lowSum, to w prevIdx jest sens siega\u0107 nie od 0 a od a_lowSum-howManyLeft\n        int minOldValue = max(0, a_lowSum - howManyLeft);\n        if (minOldValue > highSumAvail)\n        {\n            currIdx = 1 - currIdx;\n            prevIdx = 1 - prevIdx;\n            break;\n        }\n\n        const auto& v = valueAndCount.value;\n        const auto& c = valueAndCount.count;\n        const auto& vc = valueAndCount.product;\n\n        if (v == 0)\n        {\n            for (int oldValue = minOldValue; oldValue <= highSumAvail; oldValue++)\n            {\n                sums[currIdx][oldValue] = sums[prevIdx][oldValue] ? ((1 + c) * sums[prevIdx][oldValue]) % MODULUS : 0;\n            }\n        }\n        else\n        {\n            int oldValue;\n            if (highSumAvail < a_highSum)\n            {\n                oldValue = 1 + highSumAvail;\n                highSumAvail = min(highSumAvail + vc, a_highSum);\n                while (oldValue <= highSumAvail)\n                {\n                    sums[prevIdx][oldValue] = 0;\n                    oldValue++;\n                }\n            }\n\n            int m, newValue;\n            long long temp;\n            for (newValue = 0; newValue <= highSumAvail; newValue++)\n            {\n                temp = 0;\n                for (m = c, oldValue = newValue; oldValue >= minOldValue && m >= 0; m--, oldValue -= v)\n                {\n                    temp += sums[prevIdx][oldValue];\n                }\n                sums[currIdx][newValue] = temp ? (temp % MODULUS) : 0;\n            }\n        }\n\n        howManyLeft -= vc;\n        currIdx = 1 - currIdx;\n        prevIdx = 1 - prevIdx;\n    }\n\n    long long answ = 0;\n    for (int sum = a_lowSum; sum <= highSumAvail; sum++)\n    {\n        answ += sums[prevIdx][sum];\n    }\n    answ %= MODULUS;\n\n    return (int)answ;\n}\n\n```
['C++']