[HDU4336]:Card Collector(概率DP)
题目传送门
题目描述
夏川的生日就要到了。作为夏川形式上的男朋友,季堂打算给夏川买一些生日礼物。
商店里一共有种礼物。夏川每得到一种礼物,就会获得相应喜悦值$W_i$(每种礼物的喜悦值不能重复获得)。
每次,店员会按照一定的概率$P_i$(或者不拿出礼物),将第i种礼物拿出来。季堂每次都会将店员拿出来的礼物买下来。没有拿出来视为什么都没有买到,也算一次购买。
众所周知,白毛切开都是黑的。所以季堂希望最后夏川的喜悦值尽可能地高。
求夏川最后最大的喜悦值是多少,并求出使夏川得到这个喜悦值,季堂的期望购买次数。
输入格式
第一行,一个整数N,表示有N种礼物。
接下来N行,每行一个实数$P_i$和正整数$W_i$,表示第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<{W}_{i}≤{10}^{9}$,0<${P}_{i}$≤1且$\sum \limits_{i=1}^{n}{P}_{i}≤1$。
题意解释
又是血淋淋的没看懂题,再次印证了得语文者得OI,售货员一次只可能拿出一个礼物,且每个礼物只能买一次(捂脸……)
题解
偷偷看了看数据范围,喜悦值没有负值,于是乎,第一问就解决了,肯定是把所有礼物的喜悦值加起来。
那么来考虑10%的算法,N=1,我们只需要把这件礼物买下,且这件礼物的期望购买次数是$\frac{1}{P_i}$。
再来考虑30%的算法,那么每种商品都有买或不买两种状态,那么共有$2^N$种状态,$2^{{N}^{3}}$刚好跑过。
状态可以用状压(撞鸭)DP:设dp[S]表示当前状态为S,到买到所有礼物的期望步数。
剩下的那个$N^3$算法很容易想到高斯消元。
那么我们可以写出式子:
$dp[S]=\sum \limits_{i=1}^N P_i \times dp[S']+(1-\sum \limits_{i=1}^N P_i) \times dp[S]+1$
其中,S表示当前状态,S'为上一个状态,i表示没有买过的物品。
写出这个式子,你就跟正解不远了,把式子移个项:
$\sum \limits_{i=1}^N P_i \times dp[S]=\sum \limits_{i=1}^N P_i \times dp[S']+1\\dp[S]=\frac{\sum \limits_{i=1}^N P_i \times dp[S']+1}{\sum \limits_{i=1}^N P_i}$
这就是我们的DP式子啦,时间复杂度$O(2^N)$。
注意HDU输入格式不同,而且是special judge,记得输出时多保留一位即可(跟HDU数据刚了一下午,才发现是special judge,心态瞬间爆炸……)。
代码时刻
#include<bits/stdc++.h>
using namespace std;
int n;
double p[21];
long long w[21];//记得开long long
double dp[2000000];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lf%lld",&p[i],&w[i]);
p[0]+=p[i];
w[0]+=w[i];
}
printf("%lld\n",w[0]);//第一问
for(int i=(1<<n)-2;i>=0;i--)//dp
{
double flag=0.0;//分母
for(int j=1;j<=n;j++)
{
if((1<<(j-1))&i)continue;
dp[i]+=p[j]*dp[i|1<<(j-1)];
flag+=p[j];
}
dp[i]=(dp[i]+1.0)/flag;
}
cout<<fixed<<setprecision(3)<<dp[0]<<endl;//保留小数输出第二问
return 0;
}
HDU代码:
#include<bits/stdc++.h>
using namespace std;
int n;
double p[21];
double dp[2000000];
int main()
{
while(~scanf("%lld",&n))
{
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
scanf("%lf",&p[i]);
for(int i=(1<<n)-2;i>=0;i--)
{
double flag=0.0;
for(int j=1;j<=n;j++)
{
if((1<<(j-1))&i)continue;
dp[i]+=p[j]*dp[i|1<<(j-1)];
flag+=p[j];
}
dp[i]=(dp[i]+1.0)/flag;
}
cout<<fixed<<setprecision(4)<<dp[0]<<endl;//注意HDU是special judge
}
return 0;
}
rp++
[HDU4336]:Card Collector(概率DP)的更多相关文章
- hdu4336 Card Collector(概率DP,状态压缩)
In your childhood, do you crazy for collecting the beautiful cards in the snacks? They said that, fo ...
- hdu4336 Card Collector 概率dp(或容斥原理?)
题意: 买东西集齐全套卡片赢大奖.每个包装袋里面有一张卡片或者没有. 已知每种卡片出现的概率 p[i],以及所有的卡片种类的数量 n(1<=n<=20). 问集齐卡片需要买东西的数量的期望 ...
- HDU-4336 Card Collector 概率DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4336 题意:买食品收集n个卡片,每个卡片的概率分别是pi,且Σp[i]<=1,求收集n个卡片需要 ...
- HDU4336 Card Collector (概率dp+状压dp)
http://acm.hdu.edu.cn/showproblem.php?pid=4336 题意:有n种卡片,一个包里会包含至多一张卡片,第i种卡片在某个包中出现的次数为pi,问将所有种类的卡片集齐 ...
- $HDU$ 4336 $Card\ Collector$ 概率$dp$/$Min-Max$容斥
正解:期望 解题报告: 传送门! 先放下题意,,,已知有总共有$n$张卡片,每次有$p_i$的概率抽到第$i$张卡,求买所有卡的期望次数 $umm$看到期望自然而然想$dp$? 再一看,哇,$n\le ...
- hdu4336 Card Collector 状态压缩dp
Card Collector Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- HDU 4336 Card Collector 期望dp+状压
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4336 Card Collector Time Limit: 2000/1000 MS (Java/O ...
- [HDU4336]Card Collector(min-max容斥,最值反演)
Card Collector Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- hdu 4336 Card Collector(期望 dp 状态压缩)
Problem Description In your childhood, people in the famous novel Water Margin, you will win an amaz ...
随机推荐
- git reset –mixed –soft –hard命令解释。
直接看官方的解释. 其中HEAD代表版本库,index代表暂存区,另外还有一个我们增删改代码的工作区.所以官方解释翻译过来就是: --hard : 回退版本库,暂存区,工作区.(因此我们修改过的代码就 ...
- Codeforces - 1203D2 - Remove the Substring (hard version) - 双指针
https://codeforces.com/contest/1203/problem/D2 上次学了双指针求两个字符串之间的是否t是s的子序列.但其实这个双指针可以求出的是s的前i个位置中匹配t的最 ...
- 主成分分析法详解(PCA)
引用:https://blog.csdn.net/program_developer/article/details/80632779 将n维特征映射到k维上,只保留包含绝大部分方差的维度特征,而忽略 ...
- java延时队列
应用场景 1)7天自动收货 a.用户支付完成以后,把订单ID插入到内存的一个DelayQueue中,同时插入到Redis中. b.7天之内,用户点击了确认收货,则从DelayQueue中删除,从Red ...
- sql server 幂运算函数power(x,y)、square(x)、exp(x)
--POWER(x,y)函数返回x的y次乘方的结果值 --SQUARE(x)函数返回指定浮点值x的平方 --EXP(x)函数返回e的x乘方后的值 示例:select POWER(2,2), POWER ...
- python初始装饰器
python装饰器: 一,函数名的运用. 函数名是一个变量,但他是一个特殊的变量与括号配合可以执⾏行行函数的变量 1.函数名的内存地址 def func(): print("呵呵" ...
- --解决Lock wait timeout exceeded; try restarting transaction
--解决Lock wait timeout exceeded; try restarting transaction select * from information_schema.innodb_t ...
- 剑指offer-2:斐波那契数列
二.斐波那契数列 题目描述 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0). n<=39 1.递归法 1). 分析 斐波那契数列的标准公式为 ...
- 多线程之继承Thread类及多线程内存分析
*创建多线程的一种方式:继承Thread类 * java.lang.Thread是描述多线程的类,要实现多线程程序,一种方式就是继承Thread类 * 1.创建一个类Mythread让其extends ...
- (转) Java中的负数及基本类型的转型详解
(转) https://my.oschina.net/joymufeng/blog/139952 面这行代码的输出是什么? 下面两行代码的输出相同吗? 请尝试在Eclipse中运行上面的两个代码片段, ...