1. 程式人生 > >Wannafly挑戰賽23-C-收益(概率+期望DP)

Wannafly挑戰賽23-C-收益(概率+期望DP)

題目描述

小N是一家金融公司的專案經理。他準備投資一個專案,這個專案要融資L元,融資成功後會得到M元的利潤。現在有n個客戶。對於第i個客戶,他有mi元錢。小N承諾假如最後籌夠錢,會給這名客戶mi x ri的分紅。小L通過迷之手段,估計出這個客戶最後願意出錢的概率為pi。 注意,假如公司最後籌夠錢,但最終給客戶分紅比賺的多,他還是需要分出這麼多的錢(相當於虧錢了)。現在小L想知道,按前面這樣說的去做,公司最後期望能賺多少錢(有可能是負數)。

輸入描述:

第一行三個個整數n, L, M。
接下來n行,每行三個整數mi, Ri, Pi. 其中.
資料保證0 ≤ n ≤ 100, , 0 ≤ L,M ≤ 100000。
0 ≤ ri, pi ≤ 100

輸出描述:

一行一個整數代表公司最後期望收益對109 + 7取模的值。一個分數對109+7取模的值,相當於A乘上B的逆元再對109+7取模。

示例1

輸入

複製

4 89 88
99 16 80
76 1 6
81 16 70
37 3 96

輸出

複製

880839106

#include<math.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long 
#define maxn 500005
#define mod 1000000007
ll f[105][maxn],g[105][maxn],n,L,M;
ll m[maxn],r[maxn],p[maxn];
ll q(ll x,ll y)
{
	ll res=1;
	while(y)
	{
		if(y%2)
			res=res*x%mod;
		x=x*x%mod;
		y/=2;
	}
	return res;
}
int main(void)
{
	scanf("%lld%lld%lld",&n,&L,&M);
	for(int i=1;i<=n;i++)
	{
		scanf("%lld%lld%lld",&m[i],&r[i],&p[i]);
		r[i]=r[i]*m[i]%mod*q(100,mod-2)%mod;p[i]=p[i]*q(100,mod-2)%mod;
	}
	f[0][0]=1;
	for(int i=1;i<=n;i++)
		for(int j=0;j<=L;j++)
		{
			f[i][min(j+m[i],L)]=(f[i][min(j+m[i],L)]+f[i-1][j]*p[i]%mod)%mod;
			f[i][j]=(f[i][j]+f[i-1][j]*(((1-p[i])+mod)%mod)%mod)%mod;
			g[i][min(j+m[i],L)]=(g[i][min(j+m[i],L)]+p[i]*(g[i-1][j]+r[i]*f[i-1][j]%mod)%mod)%mod;
			g[i][j]=(g[i][j]+((1-p[i])+mod)%mod*g[i-1][j])%mod;
		}
	printf("%lld\n",(f[n][L]*M%mod-g[n][L]+mod)%mod);
	return 0;
}
/*
4 89 88
99 16 80
76 1 6
81 16 70
37 3 96
*/