BZOJ 4008 [HNOI2015]亚瑟王

期望DP

PoPoQQQ大爷题解

很神的DP。

如果直接考虑每一轮用掉了什么东西,对下一轮产生了什么影响,那基本是做不出来的,因为这之间的关系很多很复杂。

注意到一个物品至多被某一轮选一次。考虑所有轮一起做,记f[i][j]表示做到第i个物品时还有j轮没有选完。那么i此时可以在这j轮中被选,也可以不被选,就可以DP了。这种DP就可以避免物品与物品之间的影响了。

#include<cstdio>
#include<cstring>
#define N 233
#define R 140
#define ld long double
using namespace std;
namespace runzhe2000
{
    ld f[N][R], p[N], pow[N][R], ans;
    int d[N];
    void main()
    {
        int T; scanf("%d",&T);
        for(int n, r; T--; )
        {
            scanf("%d%d",&n,&r);
            for(int i = 1; i <= n; i++)
            {
                scanf("%Lf%d",&p[i],&d[i]);
                pow[i][0] = 1;
                for(int j = 1; j <= r; j++)
                    pow[i][j] = pow[i][j-1] * (1 - p[i]);
            }
            for(int i = 0; i < R; i++) f[0][i] = 0;
            f[0][r] = 1;
            for(int i = 1; i <= n; i++)
            {
                for(int j = 0; j <= r; j++)
                    f[i][j] = f[i-1][j] * pow[i][j] + f[i-1][j+1] * (1 - pow[i][j+1]);
                for(int j = r+1; j < R; j++) f[i][j] = 0;
            }
            ans = 0;
            for(int i = 1; i <= n; i++)
                for(int j = 1; j <= r; j++)
                    ans += d[i] * f[i-1][j] * (1 - pow[i][j]);
            printf("%.10Lf\n",ans);
        }
    }
}
int main()
{
    runzhe2000::main();
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值