F 多重背包 判断能否刚好装满

时间:2021-08-10 13:07:16

Description

有n种不同大小的数字,每种各个。判断是否可以从这些数字之中选出若干使它们的和恰好为K。

Input

首先是一个正整数T(1<=T<=100)
接下来是T组数据
每组数据第一行是一个正整数n(1<=n<=100),表示有n种不同大小的数字
第二行是n个不同大小的正整数ai(1<=ai<=100000)
第三行是n个正整数mi(1<=mi<=100000),表示每种数字有mi个
第四行是一个正整数K(1<=K<=100000)

Output

对于每组数据,如果能从这些数字中选出若干使它们的和恰好为K,则输出“Yes”,否则输出“No”,每个输出单独占一行

Sample Input

2
3
3 5 8
3 2 2
17
2
1 2
1 1
4

Sample Output

Yes
No

 # include <cstdio>
# include <cstring>
# define LL long long
using namespace std ; int n , k ;
int w[] ;
int num[] ;
int dp[] ; int main ()
{
// freopen("in.txt","r",stdin) ;
int T ;
scanf("%d" , &T) ;
while (T--)
{
scanf("%d" , &n) ;
int i , j ;
for (i = ; i <n ; i++)
scanf("%d" , &w[i]) ;
for (i = ; i <n ; i++)
scanf("%d" , &num[i]) ;
scanf("%d" , &k) ;
memset(dp , - , sizeof(dp)) ;
dp[] = ;
for (i = ; i < n ;i++)
{
for (j = ; j <=k ; j++)
{
if (dp[j] >= )
dp[j] = num[i] ;
else if (j < w[i] || dp[j - w[i]] <= )
dp[j] = - ;
else
dp[j] = dp[j - w[i]] - ;
}
}
if (dp[k] >= )
printf("Yes\n") ;
else
printf("No\n") ;
} return ;
}