题意:一个长度为n的数列(a1,a2...an),满足a[n]<=m&&a[i]>=2*a[i-1],给你n,m,求满足要求数列个数。

题解:dp[i][j]代表长度为i且a[i]=j的数列的种数,sp[i][j]代表长度为i且a[i]<=j的种数。dp[i][j]=sum(dp[i-1][k])(k<=j/2),sp[i][j]=sp[i][j-1]+dp[i][j];

View Code
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 long long dp[11][2001];
 7 long long sp[11][2001];
 8 int main()
 9 {
10     memset(dp,0,sizeof(dp));
11     memset(sp,0,sizeof(sp));
12     for(int i=1;i<=2000;i++)
13         dp[1][i]=1,sp[1][i]=i;
14     for(int i=2;i<=10;i++)
15     {
16         for(int j=(1<<(i-1));j<=2000;j++)
17         {
18             for(int k=(j>>1),len=(1<<(i-2));k>=len;k--)
19                 dp[i][j]+=dp[i-1][k];
20             sp[i][j]=sp[i][j-1]+dp[i][j];
21         }
22     }
23     int T,ca=0;
24     for(scanf("%d",&T);T;T--)
25     {
26         int n,m;
27         scanf("%d%d",&n,&m);
28         printf("Case %d: n = %d, m = %d, # lists = %lld\n",++ca,n,m,sp[n][m]);
29     }
30     return 0;
31 }