
//hdu 1203 dp(10背包) //题意是要求得到至少一份offer的最大概率, //比如样例 答案为 1-(1-0.2)*(1-0.3)=0.44,即为44.0% //则我们要求的是在承担的起支付的情况下要求得不到offer的概率最小 //即样例中的(1-0.2)*(1-0.3)就是最小的 //dp数组 保存的是 就是这个值,只要支付的起 第i 个offer且申请第i 个offer后 //得不到offer的概率能降低 则 dp[i] 就记录最低的概率 //转移方程为 dp[i] = min(dp[i], dp[i-cost[i]]*prob[i]) //prob[i]为 得不到 第i个offer的概率 //样例 //10 3 //4 0.1 //4 0.2 //5 0.3 #include <stdio.h> #include <string.h> #define eps 1e-8 #define N 10005 #define M 1005 int tot, n_offer; int cost[M]; double prob[M], dp[N]; double min(double a, double b) { return a - b > eps ? b : a; } int main() { while(scanf("%d%d", &tot, &n_offer), tot||n_offer) { for(int i = 0; i <= tot; ++i) dp[i] = 1; //初始化 花费 i 时得不到offer的最小概率为 1 for(int i = 0; i < n_offer; ++i) { scanf("%d%lf", &cost[i], &prob[i]); prob[i] = 1 - prob[i]; //1减去得到该offer的概率即为得不到得概率 } double m = 2; for(int i = 0; i < n_offer; ++i) { for(int j = tot; j >= cost[i]; --j) { //看申请第i 个offer和不申请 哪一情况得不到offer 的概率最低 dp[j] = min(dp[j], dp[j-cost[i]] * prob[i]); } } printf("%.1lf%%\n", (1 - dp[tot])*100); } return 0; }