守衛者的挑戰
阿新 • • 發佈:2018-08-05
是否 空間 get esp code guard iostream tchar namespace ,空間要開到\(400\)。
註意到因為\(double\)有\(8\)字節,\(128MB\)下該數組會導致\(MLE\)。
滾掉第一維即可。
https://www.zybuluo.com/ysner/note/1239414
題面
初始值為\(k\),現經過一段數,有\(p_i\)的概率加上第\(i\)個數\(a_i\)。問最後值\(\geq0\)且加了\(l\)個數的概率。
\(0\leq k\leq2000,0\leq n\leq200,-1\leq a_i\leq1000\)
解析
註意到\(k>200\)都是沒有意義的,於是可以把\(k\)的範圍視為\(0\leq k\leq200\)。
直接設\(f[i][j][k]\)表示處理了第\(1-i\)個數,加了\(j\)個數,值為\(k\)的概率。
決策就是是否加上這個數。
為了防止第三維變負,\(k+=200\)
註意到因為\(double\)有\(8\)字節,\(128MB\)下該數組會導致\(MLE\)。
滾掉第一維即可。
復雜度\(O(n^3)\)(\(n,k\)同階)。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #define re register #define il inline #define ll long long #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) #define fp(i,a,b) for(re int i=a;i<=b;i++) #define fq(i,a,b) for(re int i=a;i>=b;i--) using namespace std; const int mod=1e9+7,N=1e6+100; int n,l,k,sum; long double dp[2][205][410],ans; struct cha{int w;long double p;}a[N]; il ll gi() { re ll x=0,t=1; re char ch=getchar(); while(ch!=‘-‘&&(ch<‘0‘||ch>‘9‘)) ch=getchar(); if(ch==‘-‘) t=-1,ch=getchar(); while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-48,ch=getchar(); return x*t; } il int del(re int x) { if(x>400) return 400; } int main() { freopen("guard.in","r",stdin); freopen("guard.out","w",stdout); n=gi();l=gi();k=gi();k=min(k+200,400); fp(i,1,n) scanf("%Lf",&a[i].p);fp(i,1,n) a[i].w=gi(); re int now=1,nxt=0; fp(i,200,400) fp(j,l,n) dp[now][j][i]=1; fq(i,n,1) { swap(now,nxt); memset(dp[now],0,sizeof(dp[now])); fp(j,0,i) fp(v,0,400) { dp[now][j][v]+=a[i].p*dp[nxt][j+1][del(v+a[i].w)]/100; dp[now][j][v]+=(100-a[i].p)*dp[nxt][j][v]/100; } } printf("%.6Lf\n",dp[now][0][k]); fclose(stdin); fclose(stdout); return 0; }
守衛者的挑戰