• hdu1203 I NEED A OFFER!---概率DP(01背包)


    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=1203

    题目大意:
    Speakless很早就想出国,现在他已经考完了所有需要的考试,准备了所有要准备的材料,于是,便需要去申请学校了。要申请国外的任何大学,你都要交纳一定的申请费用,这可是很惊人的。Speakless没有多少钱,总共只攒了n万美元。他将在m个学校中选择若干的(当然要在他的经济承受范围内)。每个学校都有不同的申请费用a(万美元),并且Speakless估计了他得到这个学校offer的可能性b。不同学校之间是否得到offer不会互相影响。“I NEED A OFFER”,他大叫一声。帮帮这个可怜的人吧,帮助他计算一下,他可以收到至少一份offer的最大概率。(如果Speakless选择了多个学校,得到任意一个学校的offer都可以)。

    思路:
      首先,转化成对立事件来计算,至少得到一个offer的最大概率,其对立事件就是一个offer都没得到的最小概率。

      这样可以转化成01背包去做了,dp[i][j]表示的是用j万美元从前i个学校中选择学校,一份offer都收不到的最小概率。若不选择第i个学校,则dp[i][j] = dp[i-1][j],若选择了

      第i个学校,则第i个学校的不录取率是1-value[i],前i-1个学校的不录取率为dp[i-1][j-cost[i]],则有dp[i][j] = dp[i-1][j-cost[i]]*(1-value[i]),则转移式为:
           dp[i][j] = min(dp[i-1][j],dp[i-1][j-cost[i]]*(1-value[i])),答案就是1-dp[m][n],这里由于m,n较大,所以利用滚动数组求解。
     
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<string>
     6 using namespace std;
     7 typedef long long ll;
     8 int cases;
     9 int n, m;
    10 const int maxn = 1e5 + 100;
    11 double dp[maxn], v[maxn];
    12 int money[maxn];
    13 int main()
    14 {
    15     while(cin >> n >> m && (n + m))
    16     {
    17         for(int i = 0; i < m; i++)
    18         {
    19             cin >> money[i] >> v[i];
    20             v[i] = 1.0 - v[i];
    21         }
    22         for(int i = 0; i <= n; i++)dp[i] = 1.0;
    23         for(int i = 0; i < m; i++)
    24         {
    25             for(int j = n; j >= money[i]; j--)dp[j] = min(dp[j], (dp[j - money[i]]) * v[i]);
    26         }
    27         dp[n] = 1 - dp[n];
    28         printf("%.1f%%
    ", dp[n] * 100);
    29     }
    30     return 0;
    31 }
     
  • 相关阅读:
    MYSQL 字符串操作
    关于IT企业组织架构的一些思考
    关于《Java封面》一些感想
    浏览器缓存资源文件的问题
    为什么《一个程序员怎么能做出这样的事情》?
    TCP/IP协议中的参数说明
    java编译器对代码的优化
    事务属性小结
    事务的编程模型
    从阿里云os和Google之争看开源协议
  • 原文地址:https://www.cnblogs.com/fzl194/p/8676716.html
Copyright © 2020-2023  润新知