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 }
View Code

 

posted @ 2015-05-25 16:45  __Meng  阅读(515)  评论(0编辑  收藏  举报