题意:一个人手里有一笔钱 n ,有 m 所大学,分别知道这些大学的投简历花费和被录取概率,因为钱数有限,只能投一部分学校,问被录取的概率最大有多大。

这题除去计算概率以外就是一个 0 1 背包问题,所以可以完全按照 0 1 背包的方法做,只是将价值计算变成概率计算而已

dp [ j ] 表示花费了 j 时概率的最大值;

当遍历到第 i 个大学时,第 i 个大学花费 a ,被录取的概率 b ,当前被录取概率为 dp;那个加上第 i 所大学,概率就是:

(原本被录取概率)+(原本未被录取概率)* b ;

所以 dp [ j ] = max ( dp [ j ] , dp [ j - a ] + ( 1 - dp [ j - a ] * b ) );

0 1 背包毕竟做了这么多遍,不会才不应该的。

 

 1 #include<stdio.h>
 2 #include<string.h>
 3 #define max(a,b) a>b?a:b
 4 int a;
 5 double b,dp[10001];
 6 
 7 int main(){
 8     int n,m;
 9     while(scanf("%d%d",&n,&m)!=EOF&&(n!=0||m!=0)){
10         int i,j;
11         double ans=0;
12         memset(dp,0,sizeof(dp));
13         for(i=1;i<=m;i++){
14             scanf("%d%lf",&a,&b);
15             for(j=n;j>=a;j--){
16                 dp[j]=max(dp[j],dp[j-a]+(1-dp[j-a])*b);
17                 ans=max(ans,dp[j]);
18             }
19         }
20         printf("%.1lf%%\n",ans*100);
21     }
22     return 0;
23 }
View Code