UVA 10417 Gift Exchanging

UVA_10417

    如果我们设事件Ai为第1个人带来的是第i类gift,事件B为所有人的gift放一起呈现出题目中给出的每类多少个那种状态。那么P(Ai|B)就对应表示在当前这种状态下第1个人带来的是第i类gift的概率,那么剩下的问题就是把这个概率算出来就好了,然后除以第i类gift的个数就是拿1个第i类的gift且拿成功的概率。

    根据条件概率的公式有P(Ai|B)=P(AiB)/P(B),P(AiB)表示事件Ai和B同时发生的概率。由于原始gift状态的子状态个数有限,我们可以指定一个放礼物的顺序(或者拿礼物的顺序)然后进行动规来求各个状态的概率即可。

    于是我们不妨规定从第一个人开始,每人拿回去自己的礼物,拿空为止。设f[i][j]表示能达到第i个人面临礼物状态j时这种情况的概率,j不难表示,用13进制即可,剩下就是如何转移状态了,应该有f[i][j]=SUM{g[i][Ai]*f[i-1][j-Ai]},其中g[i][Ai]为第i个人带来的是Ai这个gift的概率,j-Ai表示第i个人拿走Ai后剩余的gift的状态,并不是直接做减法。

    现在有了达到各个状态的概率了,那么P(AiB)怎么表示呢?应该为g[1][Ai]*f[2][k],其中g[1][Ai]为第1个人带来的是Ai这个gift的概率,k为第1个人拿走Ai后的剩余gift的状态。P(B)怎么表示呢?应该为f[1][k],其中k为原始的gift的状态。

#include<stdio.h>
#include<string.h>
#define MAXN 13
#define MAXB 6
#define MAXD 350000
int vis[MAXN][MAXD], a[MAXB], b[MAXB], N, M, gift[MAXB];
double f[MAXN][MAXD], g[MAXN][MAXB];
double dfs(int cur, int st)
{
int i, j, k;
double ans = 0;
if(vis[cur][st])
return f[cur][st];
k = st;
for(i = 5; i > 0; i --)
{
a[i] = k % 13;
k /= 13;
}
for(i = 1; i <= 5; i ++)
if(a[i])
{
-- a[i];
for(j = 1, k = 0; j <= 5; j ++)
k = k * 13 + a[j];
ans += dfs(cur + 1, k) * g[cur][i];
++ a[i];
}
vis[cur][st] = 1;
return f[cur][st] = ans;
}
void solve()
{
int i, j, k, box;
double max, ans, res;
scanf("%d", &N);
for(i = 1; i <= 5; i ++)
scanf("%d", &gift[i]);
for(i = 1; i <= N; i ++)
for(j = 1; j <= 5; j ++)
scanf("%lf", &g[i][j]);
for(i = 1, k = 0; i <= 5; i ++)
k = k * 13 + gift[i];
memset(vis, 0, sizeof(vis));
vis[N + 1][0] = 1;
f[N + 1][0] = 1;
res = dfs(1, k);
max = -1;
for(i = 1; i <= 5; i ++)
if(gift[i])
{
-- gift[i];
for(j = 1, k = 0; j <= 5; j ++)
k = k * 13 + gift[j];
++ gift[i];
ans = f[2][k] * g[1][i] / gift[i];
if(ans / res > max + 1e-9)
{
max = ans / res;
box = i;
}
}
printf("%d %.3lf\n", box, max);
}
int main()
{
int t;
scanf("%d", &t);
while(t --)
{
solve();
}
return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
用c++解决You surely know that there are N different currencies you can deal with in our city. Let us assign unique integer number from 1 to N to each currency. Then each exchange point can be described with 6 numbers: integer A and B - numbers of currencies it exchanges, and real RAB, CAB, RBA and CBA - exchange rates and commissions when exchanging A to B and B to A respectively. Nick has some money in currency S and wonders if he can somehow, after some exchange operations, increase his capital. Of course, he wants to have his money in currency S in the end. Help him to answer this difficult question. Nick must always have non-negative sum of money while making his operations. Input The first line contains four numbers: N - the number of currencies, M - the number of exchange points, S - the number of currency Nick has and V - the quantity of currency units he has. The following M lines contain 6 numbers each - the description of the corresponding exchange point - in specified above order. Numbers are separated by one or more spaces. 1 ≤ S ≤ N ≤ 100, 1 ≤ M ≤ 100, V is real number, 0 ≤ V ≤ 103. For each point exchange rates and commissions are real, given with at most two digits after the decimal point, 10-2 ≤ rate ≤ 102, 0 ≤ commission ≤ 102. Let us call some sequence of the exchange operations simple if no exchange point is used more than once in this sequence. You may assume that ratio of the numeric values of the sums at the end and at the beginning of any simple sequence of the exchange operations will be less than 104. Output If Nick can increase his wealth, output YES, in other case output NO.
06-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值