洛谷——P2236 [HNOI2002]彩票

P2236 [HNOI2002]彩票

 

给你$m$个数,从中挑$n$个数,使得这$n$个数的倒数之和恰好等于$\frac{x}{y}$

 

常见的剪纸思路:

如果当前的倒数和加上最小可能的倒数和$>$目标解,则返回

如果当前的倒数和加上最大可能的倒数和$<$目标解,则返回

 

对于这种小数,有关精度的问题,都要设置一个变量$eps$保证精度

 

代码常数太大,只好开$O_2$水过去。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>

using namespace std;
const double eps=1e-10;
int n,m,x,y,ans,xl[60];
double aim;

bool vis[100];

void dfs(int k,double ap,int last){
    if(ap-aim>eps) return;
    if(ap+(double)(n-k+1)*1.0/(double)(last+1)+eps<aim) return;
    if((ap+(double)(n-k+1)*1.0/(double)m)>aim+eps) return;
    if(k==n+1){
        if(fabs(aim-ap)<=eps){
            ++ans;
        }
        return;
    }
    for(int i=last+1;i<=m;i++){
        if(!vis[i]){
            vis[i]=true;
            dfs(k+1,ap+1.0/(double)(i),i);
            vis[i]=false;
        }
    }
}

int main()
{
    scanf("%d%d%d%d",&n,&m,&x,&y);
    aim=(double)x/(double)y;
    int tp=1;
    for(int i=1;i<=m;i++){
        if(1.0/(double)(i)>aim) tp=i;
    }
    dfs(tp,0,0);
    printf("%d\n",ans);
    
    return 0;
}

 

posted @ 2018-10-15 20:16  清风我已逝  阅读(151)  评论(0编辑  收藏  举报