题目大意:在1~m中选n个不同的数 要求和为X/Y 求方案数
爆搜的话应该是100E左右 所以考虑加剪枝
上下界剪枝 如果当前的情况下剩余的数最大都无法到达目标或最小都无法小于目标 则剪枝
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 60
#define EPS 1e-10
using namespace std;
int n,m,ans;
double target,sum[M];
void DFS(int pos,int cnt,double now)
{
int i;
double _max=now+sum[pos+(n-cnt)-1]-sum[pos-1],_min=now+sum[m]-sum[m-(n-cnt)];
/*
for(i=1;i<=n-cnt;i++)
{
_max+=1.0/(pos+i-1);
_min+=1.0/(m-i+1);
}
*/
if( _min-target>EPS || _max-target<-EPS )
return ;
if(cnt==n)
{
++ans;
return ;
}
if(pos==m+1)
return ;
//for(i=pos;i<=m-(n-cnt)+1;i++)
// DFS(i+1,cnt+1,now+1.0/i);
DFS(pos+1,cnt,now);
DFS(pos+1,cnt+1,now+1.0/pos);
}
int main()
{
int i,x,y;
cin>>n>>m>>x>>y;
target=(double)x/y;
for(i=1;i<=m;i++)
sum[i]=sum[i-1]+1.0/i;
DFS(1,0,0.0);
cout<<ans<<endl;
return 0;
}