NOIP2016提高A组 A题 礼物—概率状压dp
题目描述
夏川的生日就要到了。作为夏川形式上的男朋友,季堂打算给夏川买一些生 日礼物。
商店里一共有n种礼物。夏川每得到一种礼物,就会获得相应喜悦值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
solution:
考场上并没有推出式子。。。
最大喜悦值就是所有Wi的和
对于10%的数据:
这是一个送分点,耐心手玩一下也能发现规律,直接1/pi就好了。
对于30%的数据:
观察到N比较小,可以考虑状压DP。设二进制状态S表示当前有哪些物品已经拿了,然后就可以转移了。具体来说:
fi=$\sum$(fj*pk)+(1-$\sum$pq)*fi+1;
然后可以列出方程组,用高斯消元求解。
时间复杂度:O(23n)
100%:
其中j状态是i状态的子集,k就是i和j相差的那一位,q是i中有的元素。前半段表示从j状态转移到k状态的期望,后半段表示i状态转移回自己的期望,因为步数多了一步所以+1。等式的两边可以消去f[i],再移项就变成了($\sum$p[q])*f[i]=$\sum$(f[j]*p[k]),($\sum$p[q]是f[i]的系数,f[i]+=p[q]*f[i])这样一来只要枚举每一个状态中的所有1就可以递推出f[(1<<n)-1]了。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#define MAXN 21
#define ll long long
using namespace std;
ll n,w[MAXN],tot_w=0,tot_s,m;
double f[1<<21],p[MAXN];
int main(){
scanf("%lld",&n);
m=(1<<n)-1;
for(int i=1;i<=n;i++){
scanf("%lf %lld",&p[i],&w[i]);
tot_w+=w[i];
}
for(int i=1;i<=m;i++){
double s=0.0;
f[i]=1;
for(int j=1;j<=n;j++){
if(i&(1<<(j-1))){
s+=p[n-j+1];
f[i]+=p[n-j+1]*f[i&(~(1<<(j-1)))];
}
}
f[i]/=s;
}
printf("%lld\n%0.3lf\n",tot_w,f[m]);
return 0;
}
ps:好像正着推是错误的,但博主还是正推过了,于是博主又打了一遍倒推的,也过了,但不知道为什么正推是错的
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
double f[<<],p[];
long long ans=,n,w[];
int main(){
scanf("%lld",&n);
for(int i=;i<n;i++){
scanf("%lf %lld",&p[i],&w[i]);
ans+=w[i];
}
f[(<<n)-]=;
for(int i=(<<n)-;i>=;i--){
double sum=;
f[i]=;
for(int j=;j<n;j++)
if(~i&(<<j)){
f[i]+=p[j]*f[i|(<<j)];
sum+=p[j];
}
f[i]/=sum;
}
printf("%lld\n%.3lf\n",ans,f[]);
return ;
}
NOIP2016提高A组 A题 礼物—概率状压dp的更多相关文章
- QDUOJ 来自xjy的签到题(bfs+状压dp)
来自xjy的签到题 Description 爱丽丝冒险来到了红皇后一个n*n大小的花园,每个格子由'.'或'#'表示,'.'表示爱丽丝可以到达这个格子,‘#’表示爱丽丝不能到达这个格子,爱丽丝每1 ...
- Codeforces Round #363 LRU(概率 状压DP)
状压DP: 先不考虑数量k, dp[i]表示状态为i的概率,状态转移方程为dp[i | (1 << j)] += dp[i],最后考虑k, 状态表示中1的数量为k的表示可行解. #incl ...
- NOIP2016提高A组 B题 【HDU3072】【JZOJ4686】通讯
题目描述 “这一切都是命运石之门的选择.” 试图研制时间机器的机关SERN截获了中二科学家伦太郎发往过去的一条短 信,并由此得知了伦太郎制作出了电话微波炉(仮). 为了掌握时间机器的技术,SERN总部 ...
- POJ2794 Double Patience[离散概率 状压DP]
Double Patience Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 694 Accepted: 368 Cas ...
- [BZOJ5006][LOJ#2290][THUWC2017]随机二分图(概率+状压DP)
https://loj.ac/problem/2290 题解:https://blog.csdn.net/Vectorxj/article/details/78905660 不是很好理解,对于边(x1 ...
- 【NOIP2016练习】T3 subset (分块,状压DP)
3 subset 3.1 题目 述 一开始你有一个空集,集合可以出现重复元素,然后有 Q 个操作 add s 在集合中加入数字 s. del s 在集合中删除数字 s.保证 s 存在 cnt s 查 ...
- [杂题]:group(状压DP+轮廓线)
题目描述 $pure$在玩一个战略类游戏.现在有一个士兵方阵,每行有若干士兵,每个士兵属于某个兵种.行的顺序不可改变,且每一行中士兵的顺序也不可改变.但由于每一行都有$C$个位置($C$不小于任一行的 ...
- [JZOJ4685] 【NOIP2016提高A组8.12】礼物
Description 夏川的生日就要到了.作为夏川形式上的男朋友,季堂打算给夏川买一些生日礼物.商店里一共有种礼物.夏川每得到一种礼物,就会获得相应喜悦值Wi(每种礼物的喜悦值不能重复获得).每次, ...
- 【NOIP2016提高A组8.12】礼物
题目 夏川的生日就要到了.作为夏川形式上的男朋友,季堂打算给夏川买一些生日礼物. 商店里一共有种礼物.夏川每得到一种礼物,就会获得相应喜悦值Wi(每种礼物的喜悦值不能重复获得). 每次,店员会按照一定 ...
随机推荐
- js对象 事件
对象 创建 var myObject = {};/* 声明对象字面变量*/ 添加值myObject.name="Jener";myObject.age=25; 代码格式 ...
- 登录操作(方法一:设置flag标志位)
登录操作(方法一:设置flag标志位) user_name="star"passwoed='123'passed_authentication=Falsecount=0for i ...
- JAVA基础_自定义泛型
泛型的来源 在Java中,泛型借鉴了C++的模版函数,从而引入了泛型. C++泛型 int add(int x,int y){ return x + y; } float add(float x.fl ...
- Spring - 整合MyBatis
目的: 使用 Spring 容器用单例模式管理 MyBatis 的 sqlSessionFactory : 使用 Spring 管理连接池.数据源等: 将 Dao / Mapper 动态代理对象注入到 ...
- 面试系列九 es 提高查询效率
,es性能优化是没有什么银弹的,啥意思呢?就是不要期待着随手调一个参数,就可以万能的应对所有的性能慢的场景.也许有的场景是你换个参数,或者调整一下语法,就可以搞定,但是绝对不是所有场景都可以这样. 一 ...
- C#真他妈神奇,一个函数都不用写就能实现一个简单的邮件发送工具
MailMessage EmaillMessage = new MailMessage( //创建一个对象 new MailAddress(loning.Te ...
- 利用HttpWebRequest模拟提交图片
利用HttpWebRequest模拟提交图片 最近在做排量post工具, 以前做的都是提交文字 这次需要post图片过去,弄了半天终于弄好了: /// <summary> /// Post ...
- rsyslog 服务器重启后 发现不能接受到外部日志 只能接受本地日志 关闭防火墙即可
rsyslog 服务器重启后 发现不能接受到外部日志 只能接受本地日志 关闭防火墙即可 1 关闭防火墙: # systemctl stop firewalld 2 将SELINUX设置为disabl ...
- 六. Default arguments 参数默认值
示例: 注意点:函数是会默认声明参数变量的,所以不需要再重新声明一次,否则会报错 错误示例如下: 函数参数的传值方法: 需要注意的是:如果要给第二个参数传值,那第一个参数要传undefined,而不能 ...
- leetcode146周赛-5130-等价多米诺骨牌对的数量
题目描述: 方法一: class Solution(object): def numEquivDominoPairs(self, dominoes): """ :type ...