7.3.5 The Balance

The Balance

Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 72 Accepted Submission(s): 50

Problem Description
Now you are asked to measure a dose of medicine with a balance and a number of weights. Certainly it is not always achievable. So you should find out the qualities which cannot be measured from the range [1,S]. S is the total quality of all the weights.
 

Input
The input consists of multiple test cases, and each case begins with a single positive integer N (1<=N<=100) on a line by itself indicating the number of weights you have. Followed by N integers Ai (1<=i<=N), indicating the quality of each weight where 1<=Ai<=100.
 

Output

            For each input set, you should first print a line specifying the number of qualities which cannot be measured. Then print another line which consists all the irrealizable qualities if the number is not zero.
 

Sample Input
3
1 2 4
3
9 2 1
 

Sample Output
0
2
4 5

意思是,用a[1],a[2]..,a[n]重量的砝码,每个砝码只能用一次,问在[1,a[1]+a[2]+..+a[n]]的范围内,有多少重量是无法通过天平称量的。

很明显,天平的话,如果是两个值 9 4 既可以称出13也可以称出5(9-4); (62ms)

只需在母函数里面加一句话,

 1 #include <cmath>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <string>
 6 #include <cstdlib>
 7 using namespace std;
 8 
 9 const int maxn=10210;
10 int cnt,n,sum,k;
11 int c1[maxn],c2[maxn],a[maxn],ans[maxn];
12 
13 void close()
14 {
15 exit(0);
16 }
17 
18 
19 void init()
20 {
21     while(scanf("%d",&n)!=EOF)
22     {
23         sum=0;
24         for (int i=1;i<=n;i++)
25             scanf("%d",&a[i]),sum+=a[i];
26         memset(c1,0,sizeof(c1));
27         memset(c2,0,sizeof(c2));
28         c1[0]=1;c1[a[1]]=1;
29         for (int i=2;i<=n;i++)
30         {
31             for (int j=0;j<=sum;j++)
32             {
33                 if (c1[j]==0) continue;
34                 k=0;
35                 c2[j+k]+=c1[j];
36                 c2[abs(j-k)]+=c1[j];
37                 k=a[i];
38                 c2[j+k]+=c1[j];
39                 c2[abs(j-k)]+=c1[j];
40             }
41             for (int j=0;j<=sum;j++)
42                 c1[j]=c2[j],c2[j]=0;
43         }
44         cnt=0;
45         for (int i=1;i<=sum;i++)
46             if (c1[i]==0)
47             {
48                 cnt++;
49                 ans[cnt]=i;
50             }
51         printf("%d
",cnt);
52         for (int i=1;i<=cnt;i++)
53             if (i==cnt)
54                 printf("%d
",ans[i]);
55             else
56                 printf("%d ",ans[i]);
57     }
58 }
59 
60 int main ()
61 {
62     init();
63     close();
64     return 0;
65 }

另外一种方法就是DP啦,我居然还跑的最快 31ms

枚举每一个砝码,然后找出[1,sum]里面那些值已经可以取到了,然后前后更新即可

 1 #include <cmath>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <string>
 6 #include <cstdlib>
 7 using namespace std;
 8 
 9 const int maxn=10210;
10 int cnt,n,sum,k;
11 int a[maxn],ans[maxn],b[maxn];
12 bool f[maxn];
13 
14 void close()
15 {
16 exit(0);
17 }
18 
19 
20 void init()
21 {
22     while(scanf("%d",&n)!=EOF)
23     {
24         sum=0;
25         for (int i=1;i<=n;i++)
26             scanf("%d",&a[i]),sum+=a[i];
27         memset(f,false,sizeof(f));
28         for (int i=1;i<=n;i++)
29         {
30             cnt=0;
31             for (int j=sum;j>=0;j--)
32                 if (f[j])
33                 {
34                     cnt++;
35                     b[cnt]=j;
36                 }
37             for (int j=1;j<=cnt;j++)
38             {
39                 f[b[j]+a[i]]=true;
40                 f[abs(b[j]-a[i])]=true;
41             }
42             f[a[i]]=true;
43         }
44         cnt=0;
45         for (int i=1;i<=sum;i++)
46             if (not f[i])
47             {
48                 cnt++;
49                 ans[cnt]=i;
50             }
51         printf("%d
",cnt);
52         for (int i=1;i<=cnt;i++)
53             if (i==cnt)
54                 printf("%d
",ans[i]);
55             else
56                 printf("%d ",ans[i]);
57     }
58 }
59 
60 int main ()
61 {
62     init();
63     close();
64     return 0;
65 }
原文地址:https://www.cnblogs.com/cssystem/p/3212348.html