#include using namespace std; /** 测试用例 2 3 5 答案 4 */ const int N = 30; int f[N]; //表示凑出j个包子的方法总数 int a[N]; //每种规格中包子的数量 int ans; //组装不出来的包子个数 //互质 bool isHz(int a, int b) { for (int i = 2; i <= min(a, b); i++) //a,b可能存在的公因子 if (a % i == 0 && b % i == 0) return false; return true; } int main() { int n; cin >> n; for (int i = 1; i <= n; i++) cin >> a[i]; //排序 sort(a + 1, a + 1 + n); //a数组中,是不是存在两个互质的数 bool flag = false; int mx;//疑似上线 for (int i = 1; i <= n; i++) { for (int j = i + 1; j <= n; j++) if (isHz(a[i], a[j])) { flag = true; mx = a[i] * a[j] - a[i] - a[j]; break; } if (flag) break; } if (!flag) { cout << -1 << endl; return 0; } /** 完全背包 f[j]表示凑出j个包子的方法总数,如果f[j]>0就凑得出,f[j]=0就凑不出。 */ f[0] = 1; // 0个包子这个状态是合法的,是可以到达的状态。而且只能是一种方案,就是不管是哪种规格,一概不要 for (int i = 1; i <= n; i++) for (int j = 1; j <= mx; j++) if (j >= a[i] && f[j - a[i]])//如果能装下,并且前序依赖可达,则当前可以继续推进 f[j]++; //枚举每个可能的数字,如果这个数字存在1种以上的方案,就是可以凑出,否则就是无法凑出 for (int i = 1; i <= mx; i++) if (!f[i]) ans++; //输出答案 cout << ans << endl; return 0; }