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
思路
有n枚砝码,每个砝码的重量已知,求这些砝码不能称出的重量。
因为是天平,所以左右两边都可以放砝码,不仅要加还要减,所以在求母函数的时候判断一下j*v[i]
和k
的大小,把减去的情况也加上
代码
#include <cstdio>
#include <cstring>
#include <cctype>
#include <stdlib.h>
#include <string>
#include <map>
#include <iostream>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
#define inf 1000000
#define mem(a,b) memset(a,b,sizeof(a))
const int N=10000+7;
int v[N],c1[N],c2[N];
int main()
{
int n,sum;
while(~scanf("%d",&n))
{
sum=0;
for(int i=1; i<=n; i++)
{
scanf("%d",&v[i]);
sum+=v[i];
}
mem(c1,0);
c1[0]=1;
for(int i=1; i<=n; i++) //硬币的每一项
{
mem(c2,0);
for(int j=0; j<=1; j++) //每个硬币有一枚
for(int k=0; k+j*v[i]<=sum; k++)
{
c2[k+j*v[i]]+=c1[k];
if(k>=j*v[i])
c2[k-j*v[i]]+=c1[k];
else
c2[j*v[i]-k]+=c1[k];
}
memcpy(c1,c2,sizeof(c2));
}
n=0;
for(int i=1; i<=sum; i++)
{
if(c1[i]==0)
n++;
}
printf("%d\n",n);
if(n)
{
int flag=1;
for(int i=1; i<=sum; i++)
{
if(c1[i]==0)
{
if(!flag)
printf(" ");
else
flag=0;
printf("%d",i);
}
}
puts("");
}
}
return 0;
}