Title Link: http://acm.hdu.edu.cn/showproblem.php?pid=1203
Title:
With $n in hand, there are m colleges and universities with a chance of admission. The application fee is a and the admission probability is b. Let's find the maximum probability of getting at least one offer.
Explanation:
To find the maximum probability of at least one offer, we can convert it to the minimum probability that we can't get one offer first.
dp[i] stores the probability that the smallest offer under I application fee can not be obtained. Here, the state transition equation is multiplication. In this case, because it is probability (real data), our dp [] must be initialized to 1, and ans must also be initialized to 1.
There is also a special case to note: n is 0, but there are schools with application fees of 0, this special treatment is OK.
Code:
#include <iostream> #include <cstdio> #include <algorithm> #include <queue> #include <cmath> #include <cstring> #include <string> #include <vector> #include <set> #include <stack> #include <list> #include <map> #define P(x) x>0?x:0 #define INF 0x3f3f3f3f using namespace std; typedef long long ll; const int maxn=1e4+5; const int maxm=1e4+5; int n,m; double dp[maxn]; double ans; struct node { int a; double b; node(int aa=0,double bb=0):a(aa),b(bb){} friend bool operator < (node n1,node n2) { return n1.a<n2.a; } }item[maxm]; void init() { for(int i=0;i<maxn;i++) { dp[i]=1; } ans=1; } int main() { while(~scanf("%d%d",&n,&m)&&(n||m)) { init(); for(int i=1;i<=m;i++) { scanf("%d%lf",&item[i].a,&item[i].b); item[i].b=1-item[i].b;//We let item[i].b save the probability of not being admitted } if(n==0) { for(int i=1;i<=m;i++) { if(item[i].a==0) ans*=item[i].b; } printf("%.1f%%\n",(1-ans)*100); continue; } for(int i=1;i<=m;i++) { for(int j=n;j>=item[i].a;j--) { dp[j]=min(dp[j-item[i].a]*item[i].b,dp[j]); } } for(int i=1;i<=n;i++) ans=min(ans,dp[i]); printf("%.1f%%\n",(1-ans)*100); } return 0; }