9.5 考试 第一题 礼物题解

本文解析了一道关于为夏川挑选生日礼物的概率DP题目,通过状压DP的方法求解最大喜悦值及期望购买次数。文章提供了完整的代码实现,帮助读者理解如何利用概率DP解决实际问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题 A: 礼物

时间限制: 1 Sec  内存限制: 256 MB

题目描述

夏川的生日就要到了。作为夏川形式上的男朋友,季堂打算给夏川买一些生 日礼物。

商店里一共有种礼物。夏川每得到一种礼物,就会获得相应喜悦值Wi(每种 礼物的喜悦值不能重复获得)。

 每次,店员会按照一定的概率Pi(或者不拿出礼物),将第i种礼物拿出来。 季堂每次都会将店员拿出来的礼物买下来。没有拿出来视为什么都没有买到,也 算一次购买。

 众所周知,白毛切开都是黑的。所以季堂希望最后夏川的喜悦值尽可能地高。 

求夏川最后最大的喜悦值是多少,并求出使夏川得到这个喜悦值,季堂的期 望购买次数。

输入

第一行,一个整数N,表示有N种礼物。

接下来N行,每行一个实数Pi和正整数Wi,表示第i种礼物被拿出来的概率和 可以获得喜悦值。

输出

第一行,一个整数表示可以获得的最大喜悦值。

 第二行,一个实数表示获得这个喜悦值的期望购买次数,保留3位小数。

样例输入

3
0.1 2
0.2 5
0.3 7

样例输出

14
12.167

提示

对于10%的数据,N = 1
对于30%的数据,N ≤ 5
对于100%的数据,N ≤ 20 ,0 < Wi ≤ 10^9 ,0 < Pi ≤ 1且∑Pi ≤ 1

 注意:本题不设spj

  这道题基本两眼看出状压+概率DP然后就默默地推了大半天的转移方程也没推出来(好尴尬……)最后拿暴力默默地过了送分的第一个点。

  其实这道题本质和 绿豆蛙的归宿 类似,都是求到达终点的步数(次数),我们大可通过状压搞一下他的每个状态,然后从所有物品都卖到的情况相回推那么转移方程就出来了

 f[i]=Σp[k]*f[j](j为比i多买一件物品的状态,k就是多买的那件物品)+(1-∑p[k])(自己转移回自己的概率)*f[i]+1

 很奇怪是吧,转移方程的右侧也出现了自身,我们只要把它稍微化简一下就可以了。

 f[i]=(Σp[k]*f[j]+1)/(Σp[k])

 然后就从最后向前推,答案就是f[0]。

  

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #define N 25
 9 using namespace std;
10 int n,va[N];
11 double p[N],f[1<<20];
12 long long sum;
13 int main()
14 {
15     scanf("%d",&n);
16     for(int i=1;i<=n;i++)
17     {
18         scanf("%lf%d",&p[i],&va[i]);
19         p[0]+=p[i];
20         sum+=va[i];
21     }
22     printf("%lld\n",sum);
23     for(int i=(1<<n)-2;i>=0;i--)
24     {
25         double sm=0.0;
26         for(int j=0;j<n;j++)
27         {
28             if(!((1<<j)&i))
29             {
30                 f[i]+=p[j+1]*f[i|(1<<j)];
31                 sm+=p[j+1];
32             }
33         }
34         f[i]++;
35         f[i]/=sm;
36     }
37     printf("%.3lf\n",f[0]);
38     return 0;
39 }
View Code

 

转载于:https://www.cnblogs.com/liutianrui/p/7497119.html

### 关于软件设计师考试下午第二的解思路 在软件设计师考试中,下午通常涉及实际编程能力的应用以及对算法设计的理解。以下是针对 afternoon session 中第二可能涉及到的内容及其解思路分析。 #### 一、理解意与背景 根据历年真的特点[^1],下午场次主要测试考生的实际开发能力和逻辑思维水平。其中第二往往围绕 **具体算法实现** 或者 **程序优化** 展开。这类目可能会要求编写一段完整的代码片段来解决问题,或者改进已有代码的功能或性能。 #### 二、常见考点解析 基于引用材料提到的信息[^2],以下是一些常见的核心知识点: - **分治法**: 如果目描述的是如何将大问题分解成若干个小规模相同性质的问题,则应考虑采用分治策略。例如快速排序、归并排序等均属于此类方法。 - **回溯法**: 当遇到路径寻找类问题(比如迷宫探索),可以运用深度优先搜索配合回溯机制完成解答。注意设置好终止条件以及退回到前一步继续尝试其他可能性的情况处理方式[^2]。 - **贪心算法**: 对某些特定场景下追求局部最优进而达到整体最佳效果的情形适用此法则。需证明每步选取都是当前状态下最好的选择才能保证最终结果正确无误。 - **动态规划(DP)**: 若发现子问题是相互关联而非独立存在的话, 动态规划将是更优的选择方案之一 。利用表格形式存储中间状态避免重复计算提高效率的同时也简化了后续操作过程。 #### 三、答技巧建议 对于该类型的试,在正式动笔之前务必仔细阅读全部内容后再做决定采取何种手段最为合适: 1. 明确所给定的数据结构类型及其特性; 2. 判断是否存在边界情况需要额外关注的地方; 3. 计算理论上的时间复杂度T(n) 和空间复杂度S(n); 4. 合理分配精力先后顺序——先易后难原则有助于稳定发挥成绩表现. 另外值得注意的一点在于关于布尔表达式的评估方面,如果涉及到短路求值的概念时记得遵循如下规则:`OR` 运算符一旦左侧为 `True`, 右侧无论为何值整个表达式即刻判定成立;而 `AND` 操作符只要任意一边呈现假象即可断言失败无需再进一步验证另一边的状态[^3]. ```python def example_short_circuit(a, b): """演示Python中的短路行为""" result = a or b # 如果a为True,则不会执行b return result print(example_short_circuit(True, False)) # 输出 True ``` #### 四、总结 综上所述,面对软件设计师考试下午卷第二道大时,应当综合考量多种因素包括但不限于上述提及的各项要点,并灵活应用相应的方法论去应对不同情境下的挑战。只有充分理解和掌握了这些基础概念之后才能够更加从容自信地迎接考场内的每一次考验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值