题意:
夹克村附近来了一个大魔王,为了保护村民们的安全,夹老爷选出勇士准备去消灭这个大魔王。为了提高勇士的战斗力,夹克老爷决定出资为这个勇士打造一把神兵――七星剑。要打造一把七星剑,得在剑上镶嵌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 "); return; } printf("%.10f ",g[7]); }