51Nod 1705 七星剑

题意:
夹克村附近来了一个大魔王,为了保护村民们的安全,夹老爷选出勇士准备去消灭这个大魔王。为了提高勇士的战斗力,夹克老爷决定出资为这个勇士打造一把神兵――七星剑。要打造一把七星剑,得在剑上镶嵌7颗魔法石,在夹克村中一共找到N种不同的魔法石,标号为1,2,3..,N,每种魔法石都有很多个,其中,第i种魔法石售价为C(i)夹克币。打造七星剑需要将魔法石一颗一颗的炼化上去,每成功炼化一次称为加了一颗星,但由于炼化过程十分看中机缘,所以不是每一次炼化都能成功。根据古书里记载在加第k颗星的时候(1<=k<=7),使用不同的魔法石会有不同的成功几率,书中给出了一些统计资料,大概是说在炼化第k颗星时,用魔法石i将有prob(k,i)的机率成功,即炼化后剑上从原有的(k-1)颗星变成k颗星,但是如果失败不但不会多出星来还会丢失lose(k,i)颗星(0<=lose(k,i)<=k-1),当然这次使用的魔法石也会被毁坏。因为魔法石比较昂贵,夹克老爷希望尽可能少的花费夹克币来打造七星剑。问夹克老爷打造七星剑花费的期望的最小值是多少夹克币?(相对于昂贵的魔法石,我们忽略所有铸剑与炼化过程的花费,只考虑花在魔法石上的费用)
题解:

 

#pragma GCC optimize (4)
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn=100+10;
const LL Inf=1e18;
int n,cost[maxn],lose[10][maxn];
double Prob[10][maxn],f[8],g[8];
void Init();
void Solve();
int main(){
        Init();Solve();
        return 0;
}
void Init(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
                scanf("%d",&cost[i]);
        for(int k=1;k<=7;k++)
                for(int i=1;i<=n;i++)
                        scanf("%lf",&Prob[k][i]);
        for(int k=1;k<=7;k++)
                for(int i=1;i<=n;i++)
                        scanf("%d",&lose[k][i]);
}
void Solve(){
        f[0]=g[0]=0;
        for(int i=1;i<=7;i++){
                f[i]=Inf;
                for(int j=1;j<=n;j++)
                        if(Prob[i][j]>0){
                                double tmp=(cost[j]+(1-Prob[i][j])*(g[i-1]-g[i-lose[i][j]-1]))/Prob[i][j];
                                f[i]=min(f[i],tmp);
                        }
                g[i]=g[i-1]+f[i];
        }
        if(g[7]>=Inf){
                printf("-1\n");
                return;
        }
        printf("%.10f\n",g[7]);
}

 

 

posted @ 2018-08-21 12:04  holy-unicorn  阅读(215)  评论(0编辑  收藏  举报