题意:一个人手里有一笔钱 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 }