思路:题目的意思就是有n种物品,m个人,每种物品有对应的价值和重量,数量无限,,但是每种物品每个人只能拿一次,然后每个人有一个最高承重值,问最后这n个人最多可以带走的价值和事多少;
显然对于个人而言,别人拿多少对自己是没有影响的,所以就只讨论每个人的情况,最后加起来就好了。
对于每个人来说就是一个01背包问题,与处理下就好了。
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <map>
#include <set>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <limits.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> ii;
const int inf = 1 << 30;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int maxn = 1001;
const int maxm = 1e5 + 10;
int p[maxn], w[maxn], dp[maxm];
int n,m;
int ans;
void solve(){
for (int i=0;i<n;i++){
for (int j=ans;j>=w[i];j--)
if (dp[j] < dp[j - w[i]] + p[i])
dp[j] = dp[j - w[i]] + p[i];
}
}
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
memset(dp, 0,sizeof dp);
ans = 0;
for (int i=0;i<n;i++){
scanf("%d%d",&p[i],&w[i]);
ans += w[i];
}
solve();
scanf("%d",&m);
int sum = 0;
while(m--){
int x;
scanf("%d",&x);
sum += *max_element(dp,dp + x + 1);
}
printf("%d\n",sum);
}
return 0;
}