1246: 背包问题
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 22 Solved: 6
[ Submit][ Status][ Discuss]
Description
有N个物品,每个物品有一定的重量,有M个袋子,它们有一定的承重,现在问使用这M个袋子,最多可以带走多少个物品.
Input
第一行一个数N 以下N行每行一个数,为每个物品的重量Ai 接下来一个数字M 以下M行每行一个数,为每个袋子的承重Bi
Output
仅一个数,为最多可以带走多少物品.
Sample Input
3
22
16
2
7
8
4
2
10
8
9
6
22
16
2
7
8
4
2
10
8
9
6
Sample Output
6
HINT
100%数据N<=5000 M<=300 Ai<=128 60%数据N<=100 M<=10 Ai<=100
Source
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<bitset>
#include<algorithm>
#include<cstring>
#include<map>
#include<stack>
#include<set>
#include<cmath>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;
const int maxn = 5E3 + 50;
int n,m,tot,c[maxn],w[maxn],sum[maxn];
bool bo[maxn];
bool DFS(int pos,int waste,int Max)
{
if (waste > Max) return 0;
if (!pos) return 1;
for (int i = n; i >= 1; i--)
if (c[i] >= w[pos] && c[i] != c[i-1]) {
c[i] -= w[pos];
int pay = 0;
if (c[i] < w[1]) pay = c[i];
c[i] -= pay;
bool flag = DFS(pos-1,waste + pay,Max);
c[i] += w[pos];
c[i] += pay;
if (flag) return 1;
}
return 0;
}
bool Judge(int now)
{
if (sum[now] > tot || w[now] > c[n]) return 0;
return DFS(now,0,tot - sum[now]);
}
int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
#endif
cin >> n;
for (int i = 1; i <= n; i++)
scanf("%d",&c[i]),tot += c[i];
cin >> m;
for (int i = 1; i <= m; i++)
scanf("%d",&w[i]);
sort(w + 1,w + m + 1);
for (int i = 1; i <= n; i++)
if (c[i] < w[1])
tot -= c[i],bo[i] = 1;
int N = 0;
for (int i = 1; i <= n; i++)
if (!bo[i]) c[++N] = c[i];
sort(c + 1,c + N + 1); n = N;
for (int i = 1; i <= m; i++)
sum[i] = sum[i-1] + w[i];
int L = 0,R = m;
while (R - L > 1) {
int mid = (L + R) >> 1;
if (Judge(mid)) L = mid;
else R = mid;
}
if (Judge(R)) cout << R;
else cout << L;
return 0;
}