
核心思想:硬币问题,小集表示大集
题目描述

思路
细想后发现,{3,9,10,6}变成了 {3,10},是不是因为9=3+3+3,6=3+3?
哦,只要大集里的数可以被其他小数表示出来,这个数就可以被删掉了。
于是,奇怪的算法诞生了!
算法
如果我们枚举,两重循环,会发现,9=3+3+3这种不可以。
难道要我dfs?
###递推!
记
f[x]=⎩⎪⎨⎪⎧012没凑出凑出了本来就有,没有凑出。
易证
f[i+a[j]]=1(f[j]>0,a[]是原数)
f[i]可以被凑出,f[i+a[j]]当然也可以被凑出
参考代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| #include <iostream> #include <algorithm> #include <cstring> using namespace std; const int maxn = 110; int f[25100], T, n, a[maxn]; int ans; int main(void) { scanf("%d", &T); while (T--) { memset(f,0,sizeof f);
ans = 0; scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d", a + i); f[a[i]] = 2; } sort(a+1,a+n+1); for(int i = 1;i <= a[n];i++) if(f[i] > 0) for(int j = 1;j <= n;j++) if(i + a[j] <= a[n])f[i+a[j]] = 1; else break; for(int i = 1;i <= a[n];i++) if(f[i] == 2)ans++; cout<<ans<<endl; } }
|
便捷下载1
便捷下载2