所有数字和大于数字积, 1<=n<=1000
观察1
..:
若xy<x+y则xy-x-y<0
即xy-x-y+1<1即(x-1)(y-1)<1, 可见x, y中至少有1
..:
若xyz<x+y+z则xyz-x-y-z<0
即xyz-xy-yz-zx+x+y+z-1+xy+yz+xz-2x-2y-2z+1<0
也(x-1)(y-1)(z-1)+(x-1)(y-1)+(y-1)(z-1)+(x-1)(z-1)<2, 可见x, y, z中至少有1
..:
猜测推广至n
观察2
..:
根据观察1可见复杂度并不是n的全子集, 至于是什么不会证QAQ:..
所以
..:
先求出1的个数, 然后枚举非1元素的子集, 看是否满足要求
排序后可以剪枝, 就是当发现已经不满足就没有必要继续枚举了
写出代码
..:
#include <bits/stdc++.h> using namespace std; int n, o, r, t; int v[1001]; int m[1001]; int s[1001]; inline void dodo(int x, int c) { int a=0, b=1; for (int i=0; i<c; i++) a+=s[i], b*=s[i]; if (b-a<=o) r+=o-(b-a); else return; for (int i=x; i<t; i++) if (v[i]) { s[c]=m[i]; v[i]--; dodo(i, c+1); v[i]++; } } inline void push(int x) { for (int i=0; i<t; i++) if (m[i]==x) { v[i]++; return; } m[t]=x; v[t]++; t++; } class Subsets { public: int findSubset(vector<int> N) { n=N.size(); sort(N.begin(), N.end()); for ( ; N[o]==1 && o<n; o++) ; for (int i=o; i<n; i++) push(N[i]); dodo(0, 0); printf("%d %d\n", n, o); return r; } };
No comments :
Post a Comment