Loading

几道背包题

Bone Collector

描述

传送门:Bone Collector

Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like to collect varies of bones , such as dog’s , cow’s , also he went to the grave … The bone collector had a big bag with a volume of V ,and along his trip of collecting there are a lot of bones , obviously , different bone has different value and different volume, now given the each bone’s value along his trip , can you calculate out the maximum of the total value the bone collector can get ?

输入

The first line contain a integer T , the number of cases. Followed by T cases , each case three lines , the first line contain two integer N , V, (N <= 1000 , V <= 1000 )representing the number of bones and the volume of his bag. And the second line contain N integers representing the value of each bone. The third line contain N integers representing the volume of each bone.

输出

One integer per line representing the maximum of the total value (this number will be less than 231).

样例

输入

5 10 

1 2 3 4 5 

5 4 3 2 1

输出

14

代码

 1 /*
 2  * =========================================================================
 3  *
 4  *       Filename:  2602.cpp
 5  *
 6  *           Link:  http://acm.hdu.edu.cn/showproblem.php?pid=2602
 7  *
 8  *        Version:  1.0
 9  *        Created:  2018/07/11 11时44分51秒
10  *       Revision:  none
11  *       Compiler:  g++
12  *
13  *         Author:  杜宁元 (https://duny31030.github.io/), duny31030@126.com
14  *   Organization:  QLU_浪在ACM
15  *
16  * =========================================================================
17  */
18 #include <bits/stdc++.h>
19 using namespace std;
20 #define ll long long
21 #define max3(a,b,c) fmax(a,fmax(b,c))
22 #define ios ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
23 const double eps = 1e-6;
24 const int INF = 0x3f3f3f3f;
25 
26 int a[1050],b[1050];
27 int d[1050][1050];
28 
29 int main()
30 {
31     ios
32 #ifdef ONLINE_JUDGE 
33 #else 
34         freopen("in.txt","r",stdin);
35     // freopen("out.txt","w",stdout); 
36 #endif
37     int T,N,V;
38     cin >> T;
39     while(T--)
40     {
41         cin >> N >> V;
42         for(int i = 1;i <= N;i++)
43         {
44             cin >> a[i];
45         }
46         for(int i = 1;i <= N;i++)
47         {
48             cin >> b[i];
49         }
50         memset(d,0,sizeof d);
51         for(int i = 1;i <= N;i++)
52         {
53             for(int j = 0;j <= V;j++)
54             {
55                 if(j >= b[i])
56                     d[i][j] = max(d[i-1][j],d[i-1][j-b[i]]+a[i]);
57                 else 
58                     d[i][j] = d[i-1][j];
59             }
60         }
61 /*      优化空间复杂度
62  *      int dp[1010];
63  *      memset(dp,0,sizeof dp);
64  *      for(int i = 1;i <= N;i++)
65  *      {
66  *          for(int j = V;j >= b[i];j--)
67  *          {
68  *              dp[j] = max(dp[j],dp[j-b[i]]+a[i]);
69  *          }
70  *      }
71  */
72         cout << d[N][V] << endl;
73     }
74 
75 
76     fclose(stdin);
77     // fclose(stdout);
78     return 0;
79 }
View Code

 

饭卡

描述

传送门:饭卡

电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额。如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够)。所以大家都希望尽量使卡上的余额最少。
某天,食堂中有n种菜出售,每种菜可购买一次。已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少。

输入

多组数据。对于每组数据:
第一行为正整数n,表示菜的数量。n<=1000。
第二行包括n个正整数,表示每种菜的价格。价格不超过50。
第三行包括一个正整数m,表示卡上的余额。m<=1000。

n=0表示数据结束。

输出

对于每组输入,输出一行,包含一个整数,表示卡上可能的最小余额。

样例

输入

1
50
5
10
1 2 3 2 1 1 2 3 2 1
50
0

输出

-45
32

思路

  • 首先将所有的菜排序
  • 求出还剩最后5元钱的时候能花掉的最多的金钱
  • 用最后的5元钱来买最贵的菜
  • 饭卡本来的金钱-能花掉最多的金钱-最贵的菜的价钱=要求的结果

代码

 1 /*
 2  * =========================================================================
 3  *
 4  *       Filename:  2546.cpp
 5  *
 6  *           Link:  http://acm.hdu.edu.cn/showproblem.php?pid=2546
 7  *
 8  *        Version:  1.0
 9  *        Created:  2018/07/12 11时40分47秒
10  *       Revision:  none
11  *       Compiler:  g++
12  *
13  *         Author:  杜宁元 (https://duny31030.github.io/), duny31030@126.com
14  *   Organization:  QLU_浪在ACM
15  *
16  * =========================================================================
17  */
18 #include <bits/stdc++.h>
19 using namespace std;
20 #define ll long long
21 #define max3(a,b,c) fmax(a,fmax(b,c))
22 #define ios ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
23 const double eps = 1e-6;
24 const int INF = 0x3f3f3f3f;
25 
26 int main()
27 {
28     ios
29 #ifdef ONLINE_JUDGE 
30 #else 
31         freopen("in.txt","r",stdin);
32     // freopen("out.txt","w",stdout); 
33 #endif
34     int n,m;
35     while(cin >> n && n != 0)
36     {
37         int a[1020];
38         int dp[1020];
39         memset(a,0,sizeof a);
40         int p;
41         p = n;
42         for(int i = 1;i <= n;i++)
43             cin >> a[i];
44         cin >> m;
45         if(m < 5)
46         {
47             cout << m << endl;
48         }
49         else 
50         {
51             memset(dp,0,sizeof dp);
52             sort(a+1,a+n+1);
53             for(int i = 1;i < n;i++)
54             {
55                 for(int j = m-5;j >= a[i];j--)
56                     dp[j] = max(dp[j],dp[j-a[i]]+a[i]);
57             }
58         cout << m-dp[m-5]-a[n] << endl;
59         }
60     }
61 
62     fclose(stdin);
63     // fclose(stdout);
64     return 0;
65 }
View Code

 

Robberies

描述

传送门:Robberies

The aspiring Roy the Robber has seen a lot of American movies, and knows that the bad guys usually gets caught in the end, often because they become too greedy. He has decided to work in the lucrative business of bank robbery only for a short while, before retiring to a comfortable job at a university. 

For a few months now, Roy has been assessing the security of various banks and the amount of cash they hold. He wants to make a calculated risk, and grab as much money as possible. 

His mother, Ola, has decided upon a tolerable probability of getting caught. She feels that he is safe enough if the banks he robs together give a probability less than this.

输入

The first line of input gives T, the number of cases. For each scenario, the first line of input gives a floating point number P, the probability Roy needs to be below, and an integer N, the number of banks he has plans for. Then follow N lines, where line j gives an integer Mj and a floating point number Pj . Bank j contains Mj millions, and the probability of getting caught from robbing it is Pj .

输出

For each test case, output a line with the maximum number of millions he can expect to get while the probability of getting caught is less than the limit set.

Notes and Constraints
0 < T <= 100
0.0 <= P <= 1.0
0 < N <= 100
0 < Mj <= 100
0.0 <= Pj <= 1.0
A bank goes bankrupt if it is robbed, and you may assume that all probabilities are independent as the police have very low funds.

样例

输入

3
0.04 3
1 0.02
2 0.03
3 0.05
0.06 3
2 0.03
2 0.03
3 0.05
0.10 3
1 0.03
2 0.02
3 0.05

输出

2

4

6

思路

  • 要求出让他不被抓情况下能抢的最多的金钱
  • 现在将他被抓的概率变为不被抓的概率,这样只需要相乘便是他安全的概率
  • 只需要这个概率小于(1-p) 他便是安全的
  • 现在将他能抢到的金钱作为第二维、银行数目作为第一维
  • 最后只需要倒序遍历一遍求出第一个安全的位置,那么这个位置的第二维便是他能抢劫的最多的金钱

代码

 1 /*
 2  * =========================================================================
 3  *
 4  *       Filename:  2955.cpp
 5  *
 6  *           Link:  http://acm.hdu.edu.cn/showproblem.php?pid=2955
 7  *
 8  *        Version:  1.0
 9  *        Created:  2018/07/15 14时30分24秒
10  *       Revision:  none
11  *       Compiler:  g++
12  *
13  *         Author:  杜宁元 (https://duny31030.github.io/), duny31030@126.com
14  *   Organization:  QLU_浪在ACM
15  *
16  * =========================================================================
17  */
18 #include <bits/stdc++.h>
19 using namespace std;
20 #define ll long long
21 #define max3(a,b,c) fmax(a,fmax(b,c))
22 #define ios ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
23 const double eps = 1e-9;
24 const int INF = 0x3f3f3f3f;
25 
26 int m[120];
27 double p[120];
28 double dp[10020];
29 
30 int main()
31 {
32     ios
33 #ifdef ONLINE_JUDGE 
34 #else 
35         freopen("in.txt","r",stdin);
36     // freopen("out.txt","w",stdout); 
37 #endif
38     int T,N;
39     double P;
40     cin >> T;
41     while(T--)
42     {
43         memset(dp,0,sizeof dp);
44         dp[0] = 1;
45         int sum = 0;
46         cin >> P >> N;
47         P = 1-P;
48         for(int i = 1;i <= N;i++)
49         {
50             cin >> m[i] >> p[i];
51             p[i] = 1-p[i];
52             sum += m[i];
53         }
54         
55         for(int i = 1;i <= N;i++)
56         {
57             for(int j = sum;j >= m[i];j--)
58             {
59                 dp[j] = max(dp[j],dp[j-m[i]]*p[i]);
60             }
61         }
62         for(int i = sum;i >= 0;i--)
63         {
64             if(P-dp[i] < eps)
65             {
66                 cout << i << endl;
67                 break;
68             }
69         }
70     }
71 
72     fclose(stdin);
73     // fclose(stdout);
74     return 0;
75 }
View Code

 

I NEED A OFFER!

描述

传送门:I NEED A OFFER!

Speakless很早就想出国,现在他已经考完了所有需要的考试,准备了所有要准备的材料,于是,便需要去申请学校了。要申请国外的任何大学,你都要交纳一定的申请费用,这可是很惊人的。Speakless没有多少钱,总共只攒了n万美元。他将在m个学校中选择若干的(当然要在他的经济承受范围内)。每个学校都有不同的申请费用a(万美元),并且Speakless估计了他得到这个学校offer的可能性b。不同学校之间是否得到offer不会互相影响。“I NEED A OFFER”,他大叫一声。帮帮这个可怜的人吧,帮助他计算一下,他可以收到至少一份offer的最大概率。(如果Speakless选择了多个学校,得到任意一个学校的offer都可以)。

输入

输入有若干组数据,每组数据的第一行有两个正整数n,m(0<=n<=10000,0<=m<=10000)
后面的m行,每行都有两个数据ai(整型),bi(实型)分别表示第i个学校的申请费用和可能拿到offer的概率。
输入的最后有两个0。

输出

每组数据都对应一个输出,表示Speakless可能得到至少一份offer的最大概率。用百分数表示,精确到小数点后一位。

样例

输入

10 3
4 0.1
4 0.2
5 0.3
0 0

输出

44.0%

Note

You should use printf(“%%”) to print a ‘%’.

思路

  • 与上题类似

代码

 1 /*
 2  * =========================================================================
 3  *
 4  *       Filename:  1203.cpp
 5  *
 6  *           Link:  http://acm.hdu.edu.cn/showproblem.php?pid=1203
 7  *
 8  *        Version:  1.0
 9  *        Created:  2018/07/15 15时16分12秒
10  *       Revision:  none
11  *       Compiler:  g++
12  *
13  *         Author:  杜宁元 (https://duny31030.github.io/), duny31030@126.com
14  *   Organization:  QLU_浪在ACM
15  *
16  * =========================================================================
17  */
18 #include <bits/stdc++.h>
19 using namespace std;
20 #define ll long long
21 #define max3(a,b,c) fmax(a,fmax(b,c))
22 #define ios ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
23 const double eps = 1e-6;
24 const int INF = 0x3f3f3f3f;
25 double dp[10020];
26 int main()
27 {
28     ios
29 #ifdef ONLINE_JUDGE 
30 #else 
31         freopen("in.txt","r",stdin);
32     // freopen("out.txt","w",stdout); 
33 #endif
34     int n,m;
35     int a[10020];
36     double b[10020];
37     while(cin >> n >> m)
38     {
39         if(n == 0 && m == 0)
40             break;
41         memset(a,0,sizeof a);   memset(b,0,sizeof b);   // aemset(dp,0,sizeof dp); 
42         for(int i = 0;i < 10020;i++)
43             dp[i] = 1.0;
44         for(int i = 1;i <= m;i++)
45         {
46             cin >> a[i] >> b[i];
47             b[i] = 1-b[i];
48         }
49 
50         for(int i = 1;i <= m;i++)
51         {
52             for(int j = n;j >= a[i];j--)
53             {
54                 dp[j] = min(dp[j],dp[j-a[i]]*b[i]);
55             }
56         }
57         //double pr = 1.0;
58         //for(int i = 1;i <= n;i++)
59         //    pr = min(pr,dp[i]);
60         //pr = 1-pr;
61         //pr *= 100;
62         printf("%.1lf%%\n",(1-dp[n])*100);
63 
64     }
65 
66     fclose(stdin);
67     // fclose(stdout);
68     return 0;
69 }

 

Big Event in HDU

描述

传送门:Big Event in HDU

Nowadays, we all know that Computer College is the biggest department in HDU. But, maybe you don’t know that Computer College had ever been split into Computer College and Software College in 2002.
The splitting is absolutely a big event in HDU! At the same time, it is a trouble thing too. All facilities must go halves. First, all facilities are assessed, and two facilities are thought to be same if they have the same value. It is assumed that there is N (0<N<1000) kinds of facilities (different value, different kinds).

输入

Input contains multiple test cases. Each test case starts with a number N (0 < N <= 50 — the total number of different facilities). The next N lines contain an integer V (0<V<=50 —value of facility) and an integer M (0<M<=100 —corresponding number of the facilities) each. You can assume that all V are different.
A test case starting with a negative integer terminates input and this test case is not to be processed.

输出

For each case, print one line containing two integers A and B which denote the value of Computer College and Software College will get respectively. A and B should be as equal as possible. At the same time, you should guarantee that A is not less than B.

样例

输入

2
10 1
20 1
3
10 1
20 2
30 1
-1

输出

20 10
40 40

思路

  • 需要让分成的两部分尽可能相等或者前者稍大于后者
  • 在输入的时候计算所有价值总和 ②
  • 然后求出能够取得的最接近一半价值总和的价值 ①
  • 如果②=2*① 则恰好可以被分为两个相等的部分
  • ②-①为较多的那一部分

代码

 1 /*
 2  * =========================================================================
 3  *
 4  *       Filename:  1171.cpp
 5  *
 6  *           Link:  http://acm.hdu.edu.cn/showproblem.php?pid=1171
 7  *
 8  *        Version:  1.0
 9  *        Created:  2018/07/15 16时52分43秒
10  *       Revision:  none
11  *       Compiler:  g++
12  *
13  *         Author:  杜宁元 (https://duny31030.github.io/), duny31030@126.com
14  *   Organization:  QLU_浪在ACM
15  *
16  * =========================================================================
17  */
18 #include <bits/stdc++.h>
19 using namespace std;
20 #define ll long long
21 #define max3(a,b,c) fmax(a,fmax(b,c))
22 #define ios ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
23 const double eps = 1e-6;
24 const int INF = 0x3f3f3f3f;
25 
26 vector<int> a;
27 int dp[200020];
28 int main()
29 {
30     ios
31 #ifdef ONLINE_JUDGE 
32 #else 
33         freopen("in.txt","r",stdin);
34     // freopen("out.txt","w",stdout); 
35 #endif
36     int n,t1,t2,sum,sum2;
37     while(cin >> n)
38     {
39         if(n < 0)
40             break;
41         a.clear();
42         sum = 0;
43         memset(dp,0,sizeof dp);
44         for(int i = 1;i <= n;i++)
45         {
46             cin >> t1 >> t2;
47             sum += t1*t2;
48             while(t2--)
49                 a.push_back(t1);
50         }
51         sum2 = sum/2;
52         for(int i = 0;i < a.size();i++)
53         {
54             for(int j = sum2;j >= a[i];j--)
55                 dp[j] = max(dp[j],dp[j-a[i]]+a[i]);
56         }
57         // printf("%d %d\n",max(dp[sum2],sum-dp[sum2]),min(dp[sum2],sum-dp[sum2]));
58         if(sum == dp[sum2]*2)
59             printf("%d %d\n",sum/2,sum/2);
60         else 
61             printf("%d %d\n",sum-dp[sum2],dp[sum2]);
62     }
63 
64 
65     fclose(stdin);
66     // fclose(stdout);
67     return 0;
68 }

 

posted @ 2021-01-20 17:45  Yiduuannng  阅读(81)  评论(0编辑  收藏  举报