经典动态规划 : 是一个背包问题。 如何选择使机会最大。
参考博客: http://www.cnblogs.com/gabo/archive/2012/04/15/2450356.html
首先根据概率知识,至少一个offer 最大,那就是一个offer都没有概率最小。
转化为求一个offer都没有的概率。
dp[i][j] 表示做出第i个选择后,使剩下来的选择得到的概率最小。
j 是花费的金钱。dp[i][j]=min(dp[i-1][j],dp[i-1][j-cost[i]]*prob[i])
然后再压缩下,把二维空间优化为1为空间
for(int j=n;j>=cost[i];j--){
dp[j]=min(dp[j],dp[j-cost[i]]*prob[i]);
}
这是一个经典问题。
需要再重头考虑一下。 01背包 完全背包等思考过程。
核心dp代码,状态转移方程
for(int i=0;i<m;i++){
for(int j=n;j>=cost[i];j--){
dp[j]=min(dp[j],dp[j-cost[i]]*prob[i]);
}
}
AC代码:
#include <iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=10005;
const double eps=1e-8;
double dp[maxn];
double prob[maxn];
int cost[maxn];
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
if(n==0&&m==0) break;
// init
for(int i=0;i<=n;i++){
dp[i]=1;
}
for(int i=0;i<m;i++){
scanf("%d%lf",&cost[i],&prob[i]);
prob[i]=1-prob[i];
}
for(int i=0;i<m;i++){
for(int j=n;j>=cost[i];j--){
dp[j]=min(dp[j],dp[j-cost[i]]*prob[i]);
}
}
printf("%.1lf%%\n",(1-dp[n])*100);
}
return 0;
}