zoukankan      html  css  js  c++  java
  • [dfs][概率] Jzoj P2941 贿赂

    Description

    议会里有N个议员,每个议员有两个属性:级别和忠诚值。


    现在你要在议会通过一个议案,一个议案通过当且仅当严格超过一半的议员投赞同票。一个议员投赞同票的几率就是忠诚值除以100。


    议员们有着奇怪的癖好:他们都喜欢吃糖。你带了K个糖果用来贿赂议员,每个糖果的作用是使得某个议员的忠诚值增加10。贿赂要在投票开始前完成。(注意任意议员的忠诚值不可能大于100)


    投票之后,如果议案没有通过,你就会很暴力地把投了反对票的所有议员暗杀掉。假设你要暗杀的议员集合是S,那么成功率就是A/(A+B);其中A是给定的常数,B是S中所有议员级别的和。当暗杀成功后你的议案就会获得通过。


    现在要求最优贿赂方案下最大的成功几率是多大。


     

    Input

    第一行三个整数N,K和A,意义如题目所述;


    接下来N行每行两个整数ai,bi分别表示每个议员的级别和忠诚值。


    Output

    一个实数表示可能的最大成功几率。保留6位小数。


     

    Sample Input

    5 3 100
    11 80
    14 90
    23 70
    80 30
    153 70
    

    Sample Output

    0.962844
     

    Data Constraint

     
     

    Hint

    对于40%的数据,保证N,K≤5


    对于100%的数据,保证N,K≤9,A,ai≤9999,bi是10的倍数

    题解

    • 题目大意:每个人有两个值a[i],b[i]为各自的等级和忠诚值,现在有k颗糖果分配出去(一个人可以拿多颗),每颗可以使一个人的忠诚值+10,若得到票数的概率没有超过一半,那么要暗杀,暗杀成功的概率为A/(A+B),其中B是所有人的等级和,问成功的概率
    • 首先,这个数据范围十分感人
    • 考虑直接dfs来枚举分配糖果的方案,这样的时间复杂度是O(n!)的
    • 那么对于n个人的忠诚值,如何求他成功的概率
    • 考虑可以递归来做,每个人就有两种情况,一种是选,就乘上选的概率,一种是不选,那就乘上不选的概率
    • 如果递归到最后的一种情况中,所得票数没有超过半数,那么就要乘上暗杀成功的概率
    • 最后所有概率取一个最大值就好了

    代码

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 #define N 10
     5 using namespace std;
     6 int n,k,A,a[N],b[N];
     7 double ans;
     8 double work(int x,int y,int B)
     9 {
    10     if (x>n) { if (y*2>n) return 1.0; else return 1.0*A/(A+B); }
    11     return 1.0*b[x]/100*work(x+1,y+1,B)+1.0*(1-1.0*b[x]/100)*work(x+1,y,B+a[x]);
    12 }
    13 void dfs(int x,int y)
    14 {
    15     if (x==n)
    16     {
    17         if (y!=0) b[x]+=y*10;
    18         if (b[x]<=100) ans=max(ans,work(1,0,0));
    19         b[x]-=y*10; return;
    20     }
    21     for (int i=0;i<=y;i++)
    22     {
    23         b[x]+=i*10;
    24         if (b[x]<=100) dfs(x+1,y-i); else  { b[x]-=i*10; break; }
    25         b[x]-=i*10;
    26     }
    27 }
    28 int main()
    29 {
    30     scanf("%d%d%d",&n,&k,&A);
    31     for (int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]);
    32     dfs(1,k),printf("%.6lf",ans);
    33 }
  • 相关阅读:
    更新部分字段 NHibernate
    无法显示 XML 页。 使用 XSL 样式表无法查看 XML 输入。请更正错误然后单击 刷新按钮,或以后重试的解决办法
    初识使用Apache MINA 开发高性能网络应用程序
    生产者消费者问题理解与Java实现
    国内HTML5前段开发框架汇总
    mongodb的sharding架构搭建
    spring配置声明式事务
    如何设计页面固定广告的效果
    结合实际问题浅谈如何使用蒙特卡罗算法模拟投资分析
    多线程实现资源共享的问题学习与总结
  • 原文地址:https://www.cnblogs.com/Comfortable/p/10291997.html
Copyright © 2011-2022 走看看