F 多重背包 判断能否刚好装满
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
1 # include <cstdio> 2 # include <cstring> 3 # define LL long long 4 using namespace std ; 5 6 int n , k ; 7 int w[100010] ; 8 int num[100010] ; 9 int dp[100010] ; 10 11 int main () 12 { 13 // freopen("in.txt","r",stdin) ; 14 int T ; 15 scanf("%d" , &T) ; 16 while (T--) 17 { 18 scanf("%d" , &n) ; 19 int i , j ; 20 for (i = 0 ; i <n ; i++) 21 scanf("%d" , &w[i]) ; 22 for (i = 0 ; i <n ; i++) 23 scanf("%d" , &num[i]) ; 24 scanf("%d" , &k) ; 25 memset(dp , -1 , sizeof(dp)) ; 26 dp[0] = 0 ; 27 for (i = 0 ; i < n ;i++) 28 { 29 for (j = 0 ; j <=k ; j++) 30 { 31 if (dp[j] >= 0) 32 dp[j] = num[i] ; 33 else if (j < w[i] || dp[j - w[i]] <= 0) 34 dp[j] = -1 ; 35 else 36 dp[j] = dp[j - w[i]] - 1 ; 37 } 38 } 39 if (dp[k] >= 0) 40 printf("Yes\n") ; 41 else 42 printf("No\n") ; 43 } 44 45 46 47 return 0 ; 48 }