zoukankan      html  css  js  c++  java
  • 7.16T1

    这是道水题!?反正大佬说它水,那他就水着吧,我反正没觉得

    我是实在没想到这道题就码了30行,不过这道题证明我现在对状压有了一丝丝敏感度,想到了要状压,并且想出了状压的状态,然而我连题都没看懂,样例也没搞出来,就随便骗了点分

    这道题的状态就是用1代表这件商品被买过了,0表示没买过,由于他每次拿出哪件物品的都有可能,当然了也可能什么都没拿出来,那这个状态就有3个来源

    1.这次买到了没买过的物品

    2.这次买到了买过的物品

    3.这次什么也没买到

    其实2和3是一样的,都是由当前状态转移到当前状态,不过2和3共同的概率我们不可能直接得到,那就只能用1减去第一种情况出现的概率,我们试着列一下转移方程

    $f[i]=∑(f[i-j]*p[j])+(1-∑p[j])*f[i]+1$

    这个东西有了上面那些应该就很好理解了j代表的是取出来的那个1,当然必要时要把它变成第j件物品,也就是它是第几个一,这个应该是状压的常见套路吧,这个+1是因为不管你从那个状态来你都要多买一次,其实这个+1就看你怎么理解了,他应该是可以有不同的理解方式,我们给这个式子移一下项,他就变成了整个样子

    $f[i]=frac{(∑(f[i-j]*p[j])+1)}{∑p[j]}$

    然后愉快的转移就好了

     1 #include<iostream>
     2 #include<cstdio>
     3 #define ll long long
     4 #define maxn 22
     5 using namespace std;
     6 int n;
     7 ll ans;
     8 int c[1<<maxn];
     9 ll W[maxn];
    10 double gl[maxn],f[1<<maxn];
    11 int lowbit(int x)
    12 {
    13     return x&(-x);
    14 }
    15 int main()
    16 {
    17     scanf("%d",&n);
    18     for(int i=0;i<n;++i)  {int ls=(1<<i);  c[ls]=i+1;}
    19     for(int i=1;i<=n;++i)  {scanf("%lf%lld",&gl[i],&W[i]);  ans+=W[i];}
    20     printf("%lld
    ",ans);
    21     for(int i=1;i<(1<<n);++i)
    22     {
    23         double sum=0;
    24         for(int k=i;k;k-=lowbit(k))
    25         {
    26             int ls1=lowbit(k);  int ls2=c[ls1];
    27             f[i]+=f[i-ls1]*gl[ls2];  sum+=gl[ls2];
    28         }
    29         f[i]=(f[i]+1.000)/sum;
    30     }
    31     printf("%0.3lf
    ",f[(1<<n)-1]);
    32     return 0;
    33 }
    View Code
  • 相关阅读:
    docker commit
    镜像原理
    docker command1
    docker镜像命令
    docker work machine
    视图
    后台管理
    模型类
    docker command
    安装virtualenv
  • 原文地址:https://www.cnblogs.com/hzjuruo/p/11201870.html
Copyright © 2011-2022 走看看