NOIP 模拟题 天上掉馅饼

1 篇文章 0 订阅

C 天上掉馅饼
文件名 输入文件 输出文件 时间限制 空间限制
bonus.pas/c/cpp bonus.in bonus.out 1s 128MB

题目描述
小 G 进入了一个神奇的世界,在这个世界,天上会掉下一些馅饼。今天,天上
会随机掉下 k 个馅饼。
每次天上掉下馅饼, 小 G 可以选择吃或者不吃(必须在下一个馅饼掉下来之前
作出选择,并且现在决定不吃的话以后也不能吃) 。
馅饼有 n 种不同的馅,根据物理定律,天上掉下这 n 种馅饼的概率相同且相互
独立。然而,每一种馅饼 i 都有一个前提馅饼集合 S i 。只有当 S i 中的馅饼都吃过
之后,才能吃第 i 种馅饼。比如说,韭菜馅馅饼的 S 中有白菜猪肉馅饼和鲜虾馅饼,
那么小 G 只有在吃过白菜猪肉馅饼和鲜虾馅饼之后,才能吃韭菜馅的馅饼。
同时,每个馅饼还有一个美味值 P i 。今天一天小 G 的幸福度,等于小 G 吃到
的所有馅饼的美味值之和。注意,P i 可能是负数。
现在考虑,在采用最优策略的前提下,小 G 这一天期望的幸福度是多少?

输入格式
第一行两个正整数 k 和 n,表示馅饼的数量和种类。
以下 n 行,每行若干个数,描述一种馅饼。其中第一个数代表美味值,随后的
整数表示该馅饼的前提馅饼,以 0 结尾。

输出格式
输出一个实数,保留 6 位小数,即在最优策略下期望的幸福度。

样例输入 1
1 2
1 0
2 0
样例输出 1
1.500000

数据范围
对于 20% 的数据,所有的馅饼都没有“前提馅饼”
对于 50% 的数据,1 ≤ k ≤ 10,1 ≤ n ≤ 10
对于 100% 的数据,1 ≤ k ≤ 100,1 ≤ n ≤ 15,美味度为属于 [−10^6 ,10^6 ] 的整

状压DP
对后续决策有影响的是什么?
现在已经吃了哪些馅饼
令F[i][s]表示考虑前i次馅饼掉落事件,吃了s这个二进制状态表示的馅饼,期望的美味值
对于每一次掉馅饼,枚举掉下来的馅饼是谁
若s&a[j]==a[j](a[i]为前提馅饼集合)
F[i][s] -> F[i+1][s|(1<<(j-1))]
注意要 /n
递推的顺序?
一个起始状态,多个目标状态,正推会导致无效状态
反着推

其实是求得的最优解/它的概率,即maxn/n^k

因为n^k不能取模,所以在dp时,每次都/n就可以了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<cstdlib>
using namespace std;
const int maxn=17;
double f[110][(1<<maxn)];
int k,n,a[110],v[110];
int main()
{
    freopen("bonus.in","r",stdin);
    freopen("bonus.out","w",stdout);
    scanf("%d%d",&k,&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&v[i]);
        while(1)
        {
            int x;scanf("%d",&x);
            if(!x) break;
            a[i]^=(1<<x-1);
        }
    }
    for(int i=k;i>=1;i--)
      for(int j=0;j<(1<<n);j++){
        for(int p=1;p<=n;p++)
          if((a[p]&j)==a[p])
             f[i][j]+=max(f[i+1][j],f[i+1][j|(1<<p-1)]+v[p]);
          else f[i][j]+=f[i+1][j];
      f[i][j]=f[i][j]/(double)n;    
    }
    printf("%.6lf",f[1][0]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值