[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 }

 

转载于:https://www.cnblogs.com/NaVi-Awson/p/7463704.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值