题意:一个长度为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];
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }