• 礼物(概率dp)


    题目大意

    夏川的生日就要到了。作为夏川形式上的男朋友,季堂打算给夏川买一些生 日礼物。
    商店里一共有种礼物。夏川每得到一种礼物,就会获得相应喜悦值Wi(每种礼物的喜悦值不能重复获得)。
    每次,店员会按照一定的概率Pi(或者不拿出礼物),将第i种礼物拿出来。 季堂每次都会将店员拿出来的礼物买下来。没有拿出来视为什么都没有买到,也算一次购买。
    众所周知,白毛切开都是黑的。所以季堂希望最后夏川的喜悦值尽可能地高。
    求夏川最后最大的喜悦值是多少,并求出使夏川得到这个喜悦值,季堂的期望购买次数。

    输入格式

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

    输出格式

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

    数据范围

    对于10%的数据,N = 1
    对于30%的数据,N ≤ 5
    对于100%的数据,N ≤ 20,0 < Wi ≤ 10^9 ,0 < Pi ≤ 1且∑Pi ≤ 1
    注意:本题不设spj

    算法分析

    • N最大只有20 所以显然可以用状压来做
    • 若我们用1来表示买了 0表示未买 则我们照样选择倒着枚举 然后举例说明
      10101这样一个状态 再买一个东西可以转移到 10111 或者 11101两种
      买到第二个位置的概率 乘上之前已经求过的 10111 的dp值 然后把每个0的位置都枚举一遍 求和 再加上( 1 - 所有0位置的概率和)(这是买空或者买到买过的东西的概率) × dp[当前状态] 就好了
    • 所以我们转移方程写出来应该是这个样子的 f[i] = (sum) (dp[j] * p[k]) + (1 - (sum)p[k]) * f[i] + 1
      移项之后可以得到 f[i] = ((sum) (dp[j] * p[k]) + 1) (div) ((sum)p[k])
      i 表示当前的状态 j表示当前状态再买一个之前没买过的物品的后的可能状态 k表示买到那一个物品的概率

    Code

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 25;
    const int Max = 1 << 20;
    double p[maxn];
    double f[Max];
    int w[maxn];
    ll sum;
    
    
    int main(){
    	int n;scanf("%d",&n);
    	for(int i = 1;i <= n;++i){
    		int x;scanf("%lf%d",&p[i],&x);
    		sum += x;
    	}
    	int S = (1 << n) - 2;
    	for(int i = S;i >= 0;--i){
    		double sump = 0;//$sum$p[k]
    		double sum = 0;//$sum$ (dp[j] * p[k])
    		for(int j = 1;j <= n;++j){//枚举买了第几个物品
    			int cur = 1 << (j-1);
    			if(cur & i)continue;//这个物品是否已经买过
    			sum += p[j] * f[cur | i];//f[cur|i] 一定在之前的时候求过了
    			sump += p[j];//让买到新物品的概率累加
    		}
    		f[i] = (sum + 1) * 1.0 / sump;//刚才推导的式子
    	}
    	printf("%lld
    %.3lf
    ",sum,f[0]);
    	return 0;
    }
    
    如初见 与初见
  • 相关阅读:
    【转】Dalvik虚拟机的启动过程分析
    【转】Android 之ActivityThead、ActivityManagerService 与activity的管理和创建
    【转】应用程序的入口是ActivityThread
    【转】Android中Application类用法
    【转】360浏览器极速与兼容模式的解释
    操作系统学习(七)--操作系统之外设显示器和键盘
    操作系统学习(六)-- 虚拟内存(页面置换算法)
    操作系统学习(五)-- 操作系统之内存管理
    操作系统学习(四)-- 操作系统之进程同步和死锁
    数据库系统学习(八)-SQL语言与数据库完整性和安全性
  • 原文地址:https://www.cnblogs.com/HISKrrr/p/13527107.html
Copyright © 2020-2023  润新知