[HNOI 2002]彩票
Description
某地发行一套彩票。彩票上写有1到M这M个自然数。彩民可以在这M个数中任意选取N个不同的数打圈。每个彩民只能买一张彩票,不同的彩民的彩票上的选择不同。
每次抽奖将抽出两个自然数X和Y。如果某人拿到的彩票上,所选N个自然数的倒数和,恰好等于X/Y,则他将获得一个纪念品。
已知抽奖结果X和Y。现在的问题是,必须准备多少纪念品,才能保证支付所有获奖者的奖品。
Input
输入文件有且仅有一行,就是用空格分开的四个整数N,M,X,Y。
Output
输出文件有且仅有一行,即所需准备的纪念品数量。 1≤X, Y≤100,1≤N≤10,1≤M≤50。输入数据保证输出结果不超过10^5。
Sample Input
2 4 3 4
Sample Output
1
题解
好早之前写的题解...代码写得丑
拿到这道题,第一个思路是以层数为关键词,搜索,
但惨痛的实践和教训的结论下,还是改用了以分母为关键词,考虑“选与不选”
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<string> 7 using namespace std; 8 const double MINN=1e-10;//浮点数计算有误差 9 int x,y,n,m; 10 double ans; 11 double pre[55];//预处理,前缀和 12 int cnt; 13 void dfs(int cen,int first,double tol)//当前第cen层,从first开始循环,当前总和为tol 14 { 15 double minn=tol+pre[m]-pre[m-(n-cen)];//tol加上未计算最小的和 16 double maxn=tol+pre[first+(n-cen)]-pre[first];//tol加上未计算最大的和 17 if (minn-ans>MINN||maxn-ans<-MINN) return;//判断过多或过少的条件 18 if (cen>=n) 19 { 20 cnt++; 21 return; 22 } 23 if (cen>=n) return; 24 dfs(cen,first+1,tol); 25 dfs(cen+1,first+1,tol+1.0/(first+1));//考虑当前选与不选 26 return; 27 } 28 int main() 29 { 30 scanf("%d%d%d%d",&n,&m,&x,&y); 31 ans=(double)x/(double)y; 32 for (int i=1;i<=m;i++) 33 pre[i]=pre[i-1]+1.0/(double)(i); 34 dfs(0,0,0); 35 printf("%d\n",cnt); 36 return 0; 37 }
博主蒟蒻,随意转载。但必须附上原文链接:http://www.cnblogs.com/NaVi-Awson/,否则你会终生找不到妹子!!!