1. 程式人生 > >HDU1203 I NEED A OFFER!-概率dp

HDU1203 I NEED A OFFER!-概率dp

I NEED A OFFER!

題意:0 1揹包問題,但與普通的01揹包有一點區別:
按照數學分析後:最大錄取率=1-最小不錄取率。
兩件事情同時發生的概率為兩個概率的乘積。又因為是求最小概率。所以
狀態轉移方程為
p[j]=min(dp[j],dp[j-uni[i].mo]*uni[i].p)
還有一個問題:如果dp被初始化為0,那麼min是不會起任何作用的,概率所能達到的最大值為1,所以應把dp陣列賦值成1.0。
那麼就沒什麼問題了。

#include<iostream>
#include<cstdio>
#define M 10100
using namespace
std; int n,m; double dp[M]; struct Bag{ int mo; double p; }uni[M]; int main() { while(1) { scanf("%d%d",&n,&m); if(n==0&&m==0) break; for(int i=1;i<=m;i++) { scanf("%d%lf",&uni[i].mo,&uni[i].p); uni[i].p=1.0
-uni[i].p;/*不被該大學錄取的概率*/ } for(int i=0;i<M;i++) dp[i]=1.0;//初始化 for(int i=1;i<=m;i++) for(int j=n;j>=uni[i].mo;j--) dp[j]=min(dp[j],dp[j-uni[i].mo]*uni[i].p);//01揹包狀態轉移方程 printf("%.1lf%%",(1-dp[n])*100),putchar('\n');//printf用“”%%“輸出一個“”%” } return
0; }