HNOI 2002 彩票

来源:互联网 发布:linux空间扩容 编辑:程序博客网 时间:2024/05/10 03:45
思路:dfs开始的思路:爆搜,2的50次方,TLE;后来改了一下,剪了一下枝,6780ms,AC;剪枝的思路:上下限:下限:从m-->当前的位置pos,用现在的倒数和now加上m-->pos的倒数和,即为MIN,如果MIN大于x/y,直接return;同理,MAX为从当前位置向后的n-pos个的倒数和,若小于x/y,rreturn;这里就用到了前缀和,sum[i]表示从1-->i的前缀倒数和,注意用double。。。。,注意:由于是倒数,所以是递减的#include<iostream>#include<cmath>using namespace std;#define LL long long#define esp 1e-10int n,m,xi,yi,ans;double sum[150],TG;void dfs(int x,int num,double now){double Min=now+sum[m]-sum[m-(n-num)];double Max=now+sum[x+(n-num)-1]-sum[x-1];if(Min-TG>esp||Max-TG<-esp) return;if(num==n){ans++; return;}if(x==m+1) return;dfs(x+1,num,now);dfs(x+1,num+1,now+1.0/x);}int main(){   scanf("%d%d%d%d",&n,&m,&xi,&yi);   TG=(double)xi/yi;   for(int i=1;i<=m;++i) sum[i]=sum[i-1]+1.0/i;   dfs(1,0,0.0);   printf("%d",ans); }

0 0
原创粉丝点击