1. 程式人生 > >LeetCode 891. Sum of Subsequence Widths (找規律)

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; } };