// [7/20/2014 Sjm]
/*
看到此题时,第一个想法是:
以P作为体积,Pj作为费用,Mj作为价值。
但是,double类型的不能作为数组下标,于是此法行不通。
于是,从另一角度考虑:
被抓的概率不能超过上限,即不被抓的概率要大于下限(下限 = 1 - 被抓概率的上限)。
以总的银行金额作为体积,每一个银行金额作为费用,不被抓的概率作为价值。
即 dp[i][j] := 抢劫了前 i 个银行,所获金额至多为 j 的最大不被抓的概率。
另外只有当每一个银行都没抓到 Roy 才可以。所以求概率时,要相乘。
由此可求出答案。
********注意********
初始化时,dp[0] = 1,若不抢劫银行,则不被抓的概率为 1。
*/
1 #include <iostream>
2 #include <cstdlib>
3 #include <cstdio>
4 #include <algorithm>
5 using namespace std;
6 const int MAX = 105;
7 const int MAX_mil = 10005;
8
9 struct node {
10 int millions;
11 double prb;
12 };
13
14 node arr[MAX];
15 int sum;
16 double P;
17 int N;
18 double dp[MAX_mil];
19
20 int Solve()
21 {
22 fill(dp, dp + sum + 1, 0);
23 dp[0] = 1;
24 for (int i = 1; i <= N; ++i) {
25 for (int j = sum; j >= arr[i].millions; --j) {
26 dp[j] = max(dp[j], dp[j - arr[i].millions] * arr[i].prb);
27 }
28 }
29 for (int j = sum; j >= 0; --j) {
30 if (dp[j] > P) {
31 return j;
32 }
33 }
34 return 0;
35 }
36
37 int main()
38 {
39 //freopen("input.txt", "r", stdin);
40 int T;
41 scanf("%d", &T);
42 while (T--) {
43 sum = 0;
44 scanf("%lf %d", &P, &N);
45 P = 1 - P;
46 for (int i = 1; i <= N; ++i) {
47 scanf("%d %lf", &arr[i].millions, &arr[i].prb);
48 arr[i].prb = 1 - arr[i].prb;
49 sum += arr[i].millions;
50 }
51 printf("%d\n", Solve());
52 }
53 return 0;
54 }