TYVJ.1864.[Poetize I]守衛者的挑戰(概率DP)
題目鏈接...無
題目:
P1864 [Poetize I]守衛者的挑戰
時間: 1000ms / 空間: 131072KiB / Java類名: Main
描述
打開了黑魔法師Vani的大門,隊員們在迷宮般的路上漫無目的地搜尋著關押applepi的監獄的所在地。突然,眼前一道亮光閃過。 “我,Nizem,是黑魔法聖殿的守衛者。如果你能通過我的挑戰,那麽你可以帶走黑魔法聖殿的地圖……”瞬間,隊員們被傳送到了一個擂臺上,最初身邊有一 個容量為K的包包。
擂臺賽一共有N項挑戰,各項挑戰依次進行。第i項挑戰有一個屬性ai,如果ai>=0,表示這次挑戰成功後可以再獲 得一個容量為ai的包包;如果ai=-1,則表示這次挑戰成功後可以得到一個大小為1 的地圖殘片。地圖殘片必須裝在包包裏才能帶出擂臺,包包沒有必要全 部裝滿,但是隊員們必須把 【獲得的所有的】地圖殘片都帶走(沒有得到的不用考慮,只需要完成所有N項挑戰後背包容量足夠容納地圖殘片即可),才能拼出完 整的地圖。並且他們至少要挑戰成功L次才能離開擂臺。
輸入格式
第一行三個整數N,L,K。
第二行N個實數,第i個實數pi表示第i項挑戰成功的百分比。
第三行N個整數,第i個整數ai表示第i項挑戰的屬性值.
輸出格式
一個整數,表示所求概率,四舍五入保留6 位小數。
輸入
樣例輸入1
3 1 0
10 20 30
-1 -1 2
樣例輸入2
5 1 2
36 44 13 83 63
-1 2 -1 2 1
輸出
樣例輸出1
0.300000
樣例輸出2
0.980387
備註
若第三項挑戰成功,如果前兩場中某場勝利,隊員們就有空間來容納得到的地圖殘片,如果挑戰失敗,根本就沒有獲得地圖殘片,不用考慮是否能裝下;若第三 項挑戰失敗,如果前兩場有勝利,沒有包來裝地圖殘片,如果前兩場都失敗,不滿足至少挑戰成功次()的要求。因此所求概率就是第三場挑戰獲勝的概率。
對於 100% 的數據,保證0<=K<=2000,0<=N<=200,-1<=ai<=1000,0<=L<=N,0<=pi<=100。
/*
答案與勝利場數、當前剩余容量(容量-碎片數)有關,所以設f[i][j][k]表示前i關中,勝了j場,容量為k的概率
如果勝利,f[i][j][k] -> f[i+1][j+1][Turn(k+a[i])] (Turn表示對應的偏移)
失敗,f[i][j][k] -> f[i+1][j][k]
用刷表法,f[i+1][j+1][Turn(k+a[i+1])] += f[i][j][Turn(k)]
f[i+1][j][Turn(k)] += f[i][j][Turn(k)]
最後只需統計 ∑f[n][j][k] (j>=勝利關數 , k>=0)
(k很大,n比較小,但實際>n的部分(容量大了)就毫無意義,所以>n直接設為n即可)
(容量-碎片數可能為負,因為只要最後n關後能帶出去就成立,中間會有放不下但最後能放下的情況。
所以負數為下標是可行的,要偏移)
*/
#include<cstdio>
#include<cctype>
using namespace std;
const int N=204;
int n,l,k,a[N];
double f[N][N][N<<1],p[N];
inline int read()
{
int now=0,f=1;register char c=getchar();
for(;!isdigit(c);c=getchar())
if(c=='-') f=-1;
for(;isdigit(c);now=now*10+c-'0',c=getchar());
return now*f;
}
inline int Turn(int x)
{
if(x>n) x=n;
return x+201;
}
int main()
{
n=read(),l=read(),k=read();
for(int i=1;i<=n;++i)
scanf("%lf",&p[i]),p[i]/=100.0;
for(int i=1;i<=n;++i)
a[i]=read();
f[0][0][Turn(k)]=1.0;
for(int i=0;i<n;++i)
for(int j=0;j<=i;++j)//勝場
for(int k=-i;k<=n;++k)//當前容量的所有可能
f[i+1][j+1][Turn(k+a[i+1])]+=f[i][j][Turn(k)]*p[i+1],
f[i+1][j][Turn(k)]+=f[i][j][Turn(k)]*(1.0-p[i+1]);
double res=0.0;
for(int i=l;i<=n;++i)//勝場數滿足
for(int j=0;j<=n;++j)//背包容量>=0,即能帶走所有碎片
res+=f[n][i][Turn(j)];
printf("%.6lf",res);
return 0;
}
TYVJ.1864.[Poetize I]守衛者的挑戰(概率DP)