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:好像正着推是错误的,但博主还是正推过了,于是博主又打了一遍倒推的,也过了,但不知道为什么正推是错的

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 double f[1<<21],p[21];
 6 long long ans=0,n,w[21];
 7 int main(){
 8     scanf("%lld",&n);
 9     for(int i=0;i<n;i++){
10         scanf("%lf %lld",&p[i],&w[i]);
11         ans+=w[i];
12     }
13     f[(1<<n)-1]=0;
14     for(int i=(1<<n)-2;i>=0;i--){
15         double sum=0;
16         f[i]=1;
17         for(int j=0;j<n;j++)
18             if(~i&(1<<j)){
19                 f[i]+=p[j]*f[i|(1<<j)];
20                 sum+=p[j];
21             }
22         f[i]/=sum;
23     }
24     printf("%lld\n%.3lf\n",ans,f[0]);
25     return 0;
26 }
View Code

 

转载于:https://www.cnblogs.com/Juve/p/11195245.html

在车辆工程中,悬架系统的性能评估和优化一直是研究的热点。悬架不仅关乎车辆的乘坐舒适性,还直接影响到车辆的操控性和稳定性。为了深入理解悬架的动态行为,研究人员经常使用“二自由度悬架模型”来简化分析,并运用“传递函数”这一数学工具来描述悬架系统的动态特性。 二自由度悬架模型将复杂的车辆系统简化为两个独立的部分:车轮和车身。这种简化模型能够较准确地模拟出车辆在垂直方向上的运动行为,同时忽略了侧向和纵向的动态影响,这使得工程师能够更加专注于分析与优化与垂直动态相关的性能指标。 传递函数作为控制系统理论中的一种工具,能够描述系统输入和输出之间的关系。在悬架系统中,传递函数特别重要,因为它能够反映出路面不平度如何被悬架系统转化为车内乘员感受到的振动。通过传递函数,我们可以得到一个频率域上的表达式,从中分析出悬架系统的关键动态特性,如系统的振幅衰减特性和共振频率等。 在实际应用中,工程师通过使用MATLAB这类数学软件,建立双质量悬架的数学模型。模型中的参数包括车轮质量、车身质量、弹簧刚度以及阻尼系数等。通过编程求解,工程师可以得到悬架系统的传递函数,并据此绘制出传递函数曲线。这为评估悬架性能提供了一个直观的工具,使工程师能够了解悬架在不同频率激励下的响应情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值