LeetCode 891. Sum of Subsequence Widths (找規律)

Given an array of integers A, consider all non-empty subsequences of A.

For any sequence S, let the width of S be the difference between the maximum and minimum element of S.

Return the sum of the widths of all subsequences of A.

As the answer may be very large, return the answer modulo 10^9 + 7.

Example 1:

Input: [2,1,3]
Output: 6
Explanation:
Subsequences are [1], [2], [3], [2,1], [2,3], [1,3], [2,1,3].
The corresponding widths are 0, 0, 0, 1, 1, 2, 2.
The sum of these widths is 6.

Note:

  • 1 <= A.length <= 20000
  • 1 <= A[i] <= 20000

解法
由題意易得,數組的順序是可以改變的,因此先把數組排好序在處理會簡單一點。在這裏插入圖片描述
本來是直接計算,沒有算出公式,得到了TLE,後來把遞歸公式給算一下,就AC了。
(還要注意溢出,因此用unsigned long long穩妥)

class Solution {
    const unsigned long long mod = 1000000007;
    unsigned long long Fn[20005]; /*Fn[i] = 2^(i-1) */
    unsigned long long Sumn[20005]; /* 2^0+2^1+...+2^n = 2^(n+1)-1 */
public:
    int sumSubseqWidths(vector<int> A) {
        sort(A.begin(), A.end());
        Fn[1] = 1;
        for(int i=2;i<=20002;i++) {
            Fn[i] = (Fn[i-1]<<1)%mod;
        }
        for(int i=0;i<=20000;i++) {
            Sumn[i] = Fn[i+2]-1;
        }

        ssize_t n = A.size();
        vector<unsigned long long> res(n+1, 0);
        unsigned long long ans = 0;
        /* native method will get TLE
        for(int i=2;i<=n;i++) {
            unsigned long long tmp = 0;
            for(int j=i-1;j>=1;j--) {
                int diff = A[i-1] - A[j-1];
                tmp += (res[j] + (Fn[j] * diff)%mod)%mod;
                tmp %= mod;
            }
            res[i] = tmp;
            ans = (ans+tmp)%mod;
        }
        */
        for(int i=2;i<=n;i++) {
            res[i] = (2*res[i-1] + Sumn[i-2]*(A[i-1]-A[i-2]))%mod;
            ans = (ans+res[i])%mod;
        }
        return ans;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章