HDU 3450 Counting Sequences(DP + 樹狀數組)
題目鏈接:點擊打開鏈接
題目大意: 統計滿足相鄰兩個數之差不超過d的子序列個數。
我們不難想到一個O(n^2)的DP算法 : 對於每一個i, d[i]表示 以i結尾的子序列個數。 那麼它將轉移到所有滿足(j >= 1 && j < i && abs(a[j]-a[i])<=d)的d[j] 。
但是由於n太大了, 這樣顯然會超時, 那麼我們來想想如何優化這個算法: 可以發現, 對於每個d[i], 其累加的部分是一個(a[i] - d, a[i] + d)的范圍內的且在i之前出現過的所有d[j]。 這恰恰符合樹狀數組的特點: 求連續和、單點更新 。
所以我們不難想到每次更新完d[i] 之後, 在a[i]這個位置上增加d[i]+1。 但是該題沒有給a[i]的數據范圍, 得到WA之後證明, 數據應該很大, 數組開不下。 那麼我們只需要離散化一下, 將數據一一映射到1~n的范圍內就好了。然後用二分查找找到映射後的代碼,用樹狀數組求解。
離散化的一個比較簡單易行的方法就是用另一個數組b復制a,然後對b進行排序去重,那麼此時b的下標就是對數組a映射後的值,用二分查找可以很容易的找到。
復雜度O(n*logn)。
細節參見代碼:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include