题目大意:给定n个数字[A1,...,An],用他们的非负倍数线性组合能生成的集合S[A1,...,An]最少可以由多少个数字生成。比如S[2, 4] = S[2],只需要一个数字。S[3,5]至少需要两个数字。
https://ac.nowcoder.com/acm/problem/21228
首先猜想需要的个数,就是n减去可以被其他数字表示的数字。一方面,去掉这些数字后,这些数字都可以再被表示出来;另一方面,不是很好证明,但是直觉上是正确的。那么就是需要能知道哪些数字可以被表示出来。当作一个无限背包问题即可。
#define MAXA 25005
int dp[MAXA];
int doit(VI& nums, int n) {
mem(dp, 0);
dp[0]=1;
int cnt = 0;
REP(i, n) {
int curr = nums[i];
if (!dp[curr]) {
++cnt;
}
REP(j, MAXA) {
if (j >= curr && dp[j - curr]) {
dp[j] = 1;
}
}
}
return cnt;
}
int main(int argc, char* argv[]) {
/* Do not use for codejam. */
/* ios_base::sync_with_stdio(false); cin.tie(NULL); */
FET(t){
readint(n);
readvi(nums, n);
SORT(nums);
printint(doit(nums, n));
}
return 0;
} 
京公网安备 11010502036488号