题目大意就是,给定n,m,要求在1到m这m个数中求出长度为n的序列,要求这个序列中有如下规律,后一个数的大小是前一个数大小的2倍或者更大
dp求解
定义d[n][m]:=长度为n,以m结尾的序列满足题目条件的个数
d[n][m]=sum(d[n-1][k]),1<<(n-2)<=k<=j/2
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
double d[12][2005]; //长度为i,以j结尾的字段的个数
double dp(int i,int j)
{
if (j<i) return d[i][j]=0;
if (d[i][j]>0) return d[i][j];
for (int k=1<<(i-2);k<=j/2;k++){
d[i][j]+=dp(i-1,k);
}
return d[i][j];
}
int main()
{
int t;memset(d,0,sizeof(d));
for (int i=1;i<=2005;i++){
d[1][i]=1;
}
for (int i=1;i<=10;i++){
for (int s=1;s<=2000;s++){
dp(i,s);
}
}
while(scanf("%d",&t)!=EOF){
for (int is=1;is<=t;is++){
int n,m;
scanf("%d%d",&n,&m);
double ans=0;
for (int i=1<<(n-1);i<=m;i++){
ans+=d[n][i];
}
printf("Case %d: n = %d, m = %d, # lists = %.0f\n",is,n,m,ans);
}
}
return 0;
}