【ZOJ 3929】Deque and Balls(普通dp)

题意:给出一个序列,按照顺序一个一个放入双端队列(可以放在头部也可以放在尾部),一个队列的美丽指数就是数列中a[i]>a[i+1]的个数,求美丽指数的期望*2^n的值。

解题思路:方便起见,我们将a[i]>a[i+1]的情况称为D情况。

由题意可以知道最后得到的序列一共有2^(n-1)个,设ans=所有序列中D情况个数的总和,最后就是求sum/2^(n-1)*2^n = 2*sum

对于将要插入的a[j]sum=原先的D情况总和*2+a[j]产生的D情况-(a[i]=a[j])的情况

如果a[j]a[i]相邻,那么a[i+1……j-1]只能放在与a[i]相异的一端,那么出现D情况的序列一共有2^(i-2)

所以a[j]D情况一共有 1+2^(i-2) (2<=i<j)

a[i]=a[j]的情况跟求j的思路类似

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 const int N=1e5+10;
 5 const ll mod=1e9+7;
 6 int a;
 7 ll f[N], sum[N], dp[N], p[N];
 8 int main(){
 9     f[0]=1, f[1]=1, sum[0]=1, sum[1]=2;
10     for(int i=2; i<N; i++) f[i] = (f[i-1]*2)%mod, sum[i] = (sum[i-1]+f[i])%mod;
11     
12     int t, n;
13     scanf("%d", &t);
14     while(t--){
15         memset(p, 0, sizeof(p));
16         scanf("%d", &n);
17         dp[0] = 0, dp[1] = 0;
18         for(int i=1; i<=n; i++){
19             scanf("%d", &a);
20             if(i>1) dp[i] = ((dp[i-1]*2)%mod + sum[i-2] - p[a] + mod)%mod;
21             p[a] = (p[a]+f[i-1])%mod;
22         }
23         printf("%lld\n", (dp[n]*2)%mod);
24     }
25     return 0;
26 }

 

posted @ 2016-04-11 23:30  穿破石  阅读(294)  评论(0编辑  收藏  举报