Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3083 Accepted Submission(s): 1160
1 #include <stdio.h>
2 #include <string.h>
3
4 int main()
5 {
6 int t, n, m, f[110], i, c, w, v;
7 double p, cf;
8
9
10 scanf("%d", &t);
11 while (t--)
12 {
13 scanf("%lf%d", &p, &n);
14 m = (int)100 * p;
15
16 memset(f, 0, sizeof(f));
17
18 for (i = 1; i <= n; i++)
19 {
20 scanf("%d%lf", &w, &cf);
21 c = (int)100 * cf;
22 for (v = m; v >= c; v--)
23 {
24 if (f[v] < f[v - c] + w)
25 {
26 f[v] = f[v - c] + w;
27 }
28 }
29 }
30
31 printf("%d\n", f[m]);
32
33 }
34 return 0;
35 }
1 #include <stdio.h>
2 #include <string.h>
3
4 int main()
5 {
6 int t, n, i, c[110], v, cost;
7 double p, p1[110],f[10010];
8
9
10 scanf("%d", &t);
11 while (t--)
12 {
13 scanf("%lf%d", &p, &n);
14
15 memset(f, 0, sizeof(f));//刚才说到初始化的问题。如这里,其实可以不一定是0,但是这里的初始化是为了
16 //其中一个是已经赋值,而另一个未赋过值,时一定选择赋过值的那个,(类比用max标记最大值是max=-INF为初值)。所以,这里如果有赋过
17 //值的话都大于0,所以其实f[1.....n]赋初值为 <= 0的数都可以。【必选第一个值原则】
18
19
20 f[0] = 1;//而这个初值一定要为1,因为当没偷过1分钱的时候,是不可能被抓的既【符合实际原则】
21
22
23 cost = 0;
24 for (i = 1; i <= n; i++)
25 {
26 scanf("%d%lf", &c[i], &p1[i]);
27 cost += c[i];
28
29 }
30
31
32
33 for (i = 1; i <= n; i++)//记录过程。
34 {
35 for (v = cost; v >= c[i]; v--)
36 {
37 if (f[v] < f[v - c[i]] * (1 - p1[i]))
38 {
39 f[v] = f[v - c[i]] * (1 - p1[i]);
40 }
41 }
42 }
43
44
45
46 for (i = cost; i >= 0; i--)//找适合答案过程。
47 {
48 if (f[i] >= (1 - p))
49 {
50 break;
51 }
52 }
53 printf("%d\n", i);
54
55 }
56 return 0;
57 }
#include <iostream> #include <algorithm> using namespace std; const int M = 10010;//V const int N = 110;//n int c[N],/* w[N],*/ n1[N];//c:费用 w:价值 n1:数量 double w[N]; double f[M];//f[与V有关],c和w[与n]有关 int v, V, V1;//V:容量 V1:容量2 int n; //01背包 void ZeroOnePack(int c, double w) { for (int v = V; v >= c; v--) { f[v] = max(f[v], f[v-c] * w); } } //完全背包 void CompletePack(int c, int w) { for (int v = c; v <= V; v++) { f[v] = max(f[v], f[v-c] + w); } } //多重背包,二进制。 void MultiplePack(int c, int w, int n1) { if (c * n1 >= V) { CompletePack(c, w); } else { int k = 1; while (k < n1) { ZeroOnePack(k*c, k*w); n1 -= k; k <<= 1; } ZeroOnePack(n1*c, n1*w); } } int main() { int t; scanf("%d", &t); while (t--) { double lowest; scanf("%lf%d", &lowest, &n); V = 0; for (int i = 0; i < n; i++) { scanf("%d%lf", c + i, w + i); w[i] = 1 - w[i];//转成不被抓的概率 V += c[i]; } memset(f, 0, sizeof(f));//没有符合条件(恰好装满)的,为了保证后面改变该值,所以初始化为最小值(即最不优解) f[0] = 1;//符合条件的最优 for (int i = 0; i < n; i++) { ZeroOnePack(c[i], w[i]); } int i; for (i = V; i > 0; i--)//从后往前扫找答案 { if (1 - f[i] < lowest) { break; } } printf("%d\n", i); } return 0; }