Find the nondecreasing subsequencesTime Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1711 Accepted Submission(s): 625
Problem Description
How many nondecreasing subsequences can you find in the sequence S = {s1, s2, s3, ...., sn} ? For example, we assume that S = {1, 2, 3}, and you can find seven nondecreasing subsequences, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}.
Input
The input consists of multiple test cases. Each case begins with a line containing a positive integer n that is the length of the sequence S, the next line contains n integers {s1, s2, s3, ...., sn}, 1 <= n <= 100000, 0 <= si <= 2^31.
Output
For each test case, output one line containing the number of nondecreasing subsequences you can find from the sequence S, the answer should % 1000000007.
Sample Input
Sample Output
|
题意:给你n个数,问你不下降子序列的个数%1000000007。
分析:明显的dp,用dp[i]表示以a[i]结尾的不下降子序列的个数。显然有
dp[i] = sigama(dp[j]) + 1 其中(1 <= j < i && a[j] <= a[i])。 最后ans = sigma(dp[i]) 其中(1 <= i <= n)
代码:贴出一部分 没有取余操作。
LL a[MAXN]; LL dp[MAXN]; int main() { int n; while(~Ri(n)) { for(int i = 1; i <= n; i++) Ri(a[i]); CLR(dp, 0); LL ans = 0; for(int i = 1; i <= n; i++) { dp[i] = 1; for(int j = 1; j < i; j++) if(a[i] >= a[j]) dp[i] += dp[j]; ans += dp[i]; } Pl(ans); } return 0; }
由于a[j] <= a[i] 且 (i <= j < i)我们可以考虑利用逆序数的性质来求解,而树状数组是求解逆序数的最佳工具。
AC代码:树状数组优化dp 求出每个数前面有多少个数小于或等于它 就可以了。
#include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> #include <map> #include <string> #include <vector> #define lson o<<1|1, l, mid #define rson o<<1, mid+1, r #define ll o<<1 #define rr o<<1|1 #define INF 0x3f3f3f3f #define eps 1e-8 #define debug printf("1\n") #define MAXN 101000 #define MAXM 100000 #define LL long long #define CLR(a, b) memset(a, (b), sizeof(a)) #define W(a) while(a--) #define Ri(a) scanf("%d", &a) #define Pi(a) printf("%d\n", (a)) #define Rl(a) scanf("%lld", &a) #define Pl(a) printf("%lld\n", (a)) #define Rs(a) scanf("%s", a) #define Ps(a) printf("%s\n", (a)) #define MOD 1000000007 using namespace std; int a[MAXN]; int dp[MAXN]; int n; int lowbit(int x){ return x & (-x); } int update(int x, int d) { while(x <= n) { dp[x] += d; dp[x] %= MOD; x += lowbit(x); } } int sum(int x) { int s = 0; while(x > 0) { s += dp[x]; s %= MOD; x -= lowbit(x); } return s; } struct MES{ int val, id; }; MES num[MAXN]; bool cmp(MES a, MES b){ if(a.val != b.val) return a.val < b.val; else return a.id < b.id; } int main() { while(~Ri(n)) { CLR(dp, 0); for(int i = 1; i <= n; i++) Ri(num[i].val), num[i].id = i; sort(num+1, num+n+1, cmp); num[0].id = 0; for(int i = 1; i <= n; i++) { int add = sum(num[i].id-1); add %= MOD; update(num[i].id, add+1); } Pi(sum(n)%MOD); } return 0; }