hdu 3450 树状数组 + dp
转自 http://www.cppblog.com/baby-fly/archive/2010/08/03/122027.aspx?opt=admin 很显然是动态规划。dp[i]表示前i个数有多少个有效的子序列。那么 dp[i]=dp[i-1]+A。 A是前面i-1个数中,与i的差值不超过d的以该数结尾的有效的子序列的个数 的和。我们可以用另外一个数组sub[i]表示以i结尾的有效的子序列的个数。 dp与sub的不同之处是dp中的子序列不一定是以第i个数结尾的。 sub[i]= sigma sub[k] ,( abs(numk],num[i])<=d )。 由于求sub的时间复杂度为O(n^2),而n太大,因此需要离散化后用树状数组。 树状数组求和是一段连续的,而sub要求和的是位于区间[num[i]-d,num[i]+d],所以要对num排序,这样就能把 [num[i]-d,num[i]+d]放到连续的区间中。 #include < iostream > #include < algorithm > using namespace std; #define mod 9901 const int maxn = 100010 ; struct node { int value,index; }num[maxn]; int dp[maxn],cnt[maxn],tree[maxn];