「NOIP模擬」禮物【狀態壓縮】【期望DP】

Description

夏川的生日就要到了。作爲夏川形式上的男朋友,季堂打算給夏川買一些生日禮物。
商店裏一共有種禮物。夏川每得到一種禮物,就會獲得相應喜悅值Wi(每種禮物的喜悅值不能重複獲得)。
每次,店員會按照一定的概率Pi(或者不拿出禮物),將第i種禮物拿出來。季堂每次都會將店員拿出來的禮物買下來。
衆所周知,白毛切開都是黑的。所以季堂希望最後夏川的喜悅值儘可能地高。
求夏川最後最大的喜悅值是多少,並求出使夏川得到這個喜悅值,季堂的期望購買次數。

Input

第一行,一個整數N,表示有N種禮物。
接下來N行,每行一個實數Pi和正整數Wi,表示第i種禮物被拿出來的概率和可以獲得喜悅值。

Output

第一行,一個整數表示可以獲得的最大喜悅值。
第二行,一個實數表示獲得這個喜悅值的期望購買次數,保留3位小數。

f[s]f[s]表示買了狀態ss中的物品的期望,s=s2i,iss'=s-2^i,i∈s

於是則有:
f[s]=f[s]p1pf[s]=\frac{\sum f[s']*p-1}{\sum p}

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define db double
#define sg string
#define ll long long
#define rel(i,x,y) for(ll i=(x);i<(y);i++)
#define rep(i,x,y) for(ll i=(x);i<=(y);i++)
#define red(i,x,y) for(ll i=(x);i>=(y);i--)
#define res(i,x) for(ll i=head[x];i;i=nxt[i])
using namespace std;

const ll N=20;
const ll Inf=1e18;
const ll Mod=1e9+7;
const db Eps=1e-10;

ll n,ans,all;
db f[1<<N],p[N+5];

void File() {
	freopen("gift.in","r",stdin);
	freopen("gift.out","w",stdout);
}

int main() {
//	File();
	
	scanf("%lld",&n);all=(1<<n)-1;
	
	ll val;
	
	rep(i,1,n) scanf("%lf%lld",&p[i],&val),ans+=val;
	
	rep(i,1,all) {
		db pp=0.0;
		
		rep(j,1,n) if(i&(1<<(j-1))) f[i]=f[i]+f[i-(1<<(j-1))]*p[j],pp=pp+p[j];
		
        f[i]=(f[i]+1)/pp;
	}
	
	printf("%lld\n%.3lf",ans,f[all]);

	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章