[Poetize I]守卫者的挑战
描述 Description
打开了黑魔法师Vani的大门,队员们在迷宫 般的路上漫无目的地搜寻着关押applepi的监狱的所在地。突然,眼前一道亮光闪过。“我,Nizem,是黑魔法圣殿的守卫者。如果你能通过我的挑战, 那么你可以带走黑魔法圣殿的地图……”瞬间,队员们被传送到了一个擂台上,最初身边有一个容量为K的包包。
擂台赛一共有N项挑战,各项挑战依 次进行。第i项挑战有一个属性ai,如果ai>=0,表示这次挑战成功后可以再获得一个容量为ai的包包;如果ai=-1,则表示这次挑战成功后可 以得到一个大小为1 的地图残片。地图残片必须装在包包里才能带出擂台,包包没有必要全部装满,但是队员们必须把 【获得的所有的】地图残片都带走(没有 得到的不用考虑,只需要完成所有N项挑战后背包容量足够容纳地图残片即可),才能拼出完整的地图。并且他们至少要挑战成功L次才能离开擂台。
队员们一筹莫展之时,善良的守卫者Nizem帮忙预估出了每项挑战成功的概率,其中第i项挑战成功的概率为pi%。现在,请你帮忙预测一下,队员们能够带上他们获得的地图残片离开擂台的概率。
擂台赛一共有N项挑战,各项挑战依 次进行。第i项挑战有一个属性ai,如果ai>=0,表示这次挑战成功后可以再获得一个容量为ai的包包;如果ai=-1,则表示这次挑战成功后可 以得到一个大小为1 的地图残片。地图残片必须装在包包里才能带出擂台,包包没有必要全部装满,但是队员们必须把 【获得的所有的】地图残片都带走(没有 得到的不用考虑,只需要完成所有N项挑战后背包容量足够容纳地图残片即可),才能拼出完整的地图。并且他们至少要挑战成功L次才能离开擂台。
队员们一筹莫展之时,善良的守卫者Nizem帮忙预估出了每项挑战成功的概率,其中第i项挑战成功的概率为pi%。现在,请你帮忙预测一下,队员们能够带上他们获得的地图残片离开擂台的概率。
题解:
三维DP,只不过下标有负数比较麻烦,无奈写了p(貌似c++用个宏就ok了?)
枚举每个状态,按输赢来递推即可。吐槽一下此题数据是有多弱,按理说应该开20W*2*200的数组,M成翔,改成500*2*200就过了。。。
代码:
View Code
三维DP,只不过下标有负数比较麻烦,无奈写了p(貌似c++用个宏就ok了?)
枚举每个状态,按输赢来递推即可。吐槽一下此题数据是有多弱,按理说应该开20W*2*200的数组,M成翔,改成500*2*200就过了。。。
代码:
1 var i,j,k,n,l,t,mx:longint; 2 a,b:array[0..250] of longint; 3 f:array[0..1,-200..5000,0..200] of double; 4 ans:double; 5 begin 6 read(n);read(l);read(mx); 7 for i:=1 to n do read(b[i]); 8 for i:=1 to n do read(a[i]); 9 f[0,mx,0]:=1.0;t:=0; 10 for i:=1 to n do 11 begin 12 t:=1-t;if(a[i]>0)then inc(mx,a[i]); 13 for j:=-n to mx do 14 for k:=0 to i do 15 begin 16 f[t,j,k]:=f[1-t,j,k]*(100-b[i])/100; 17 if(k>0)then f[t,j,k]:=f[t,j,k]+f[1-t,j-a[i],k-1]*b[i]/100; 18 end; 19 end; 20 for i:=0 to mx do for j:=l to n do ans:=ans+f[t,i,j]; 21 writeln(ans:0:6); 22 end.
hzwer的做法比较好:
首先因为n最大为200,所以背包容量大于200是没有意义的
所以用f[i][j][k]表示前i场胜j场背包容量k的概率
为了防止容量变成负数
可以对挑战进行排序
代码:
View Code
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<set> 6 #include<vector> 7 #include<algorithm> 8 #define inf 1000000000 9 #define ll long long 10 using namespace std; 11 inline int read() 12 { 13 int x=0,f=1;char ch=getchar(); 14 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 15 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 16 return x*f; 17 } 18 int n,l,K; 19 double f[205][205][205]; 20 double ans; 21 struct data{double p;int v;}a[205]; 22 bool operator<(data a,data b) 23 { 24 return a.v>b.v; 25 } 26 int main() 27 { 28 //freopen("guard.in","r",stdin); 29 //freopen("guard.out","w",stdout); 30 n=read();l=read();K=read(); 31 for(int i=1;i<=n;i++) 32 { 33 scanf("%lf",&a[i].p); 34 a[i].p/=100; 35 } 36 for(int i=1;i<=n;i++)a[i].v=read(); 37 sort(a+1,a+n+1); 38 f[0][0][min(K,200)]=1; 39 for(int i=0;i<n;i++) 40 for(int k=0;k<=i;k++) 41 for(int j=0;j<=n;j++) 42 { 43 f[i+1][k][j]+=f[i][k][j]*(1-a[i+1].p); 44 int t=j+a[i+1].v; 45 if(t<0)continue; 46 t=min(t,n); 47 f[i+1][k+1][t]+=f[i][k][j]*a[i+1].p; 48 } 49 for(int i=0;i<=n;i++) 50 for(int j=l;j<=n;j++) 51 ans+=f[n][j][i]; 52 printf("%.6lf",ans); 53 return 0; 54 }