「JoyOI1096」数字组合
题目描述
在N个数中找出其和为M的若干个数。先读入正整数N(1< N< 100)和M(1< M< 10000), 再读入N个正数(可以有相同的数字,每个数字均在1000以内), 在这N个数中找出若干个数, 使它们的和是M, 把满足条件的数字组合都找出来以统计组合的个数,输出组合的个数(不考虑组合是否相同)。要求你的程序运行时间不超过1秒。
输入
第一行是两个数字,表示N和M。 第二行起是N个数。
输出
就一个数字,表示和为M的组合的个数。
样例输入
4 4 1 1 2 2
样例输出
3
代码
dp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#include<iostream> using namespace std; int f[10001]={1}; int main() { int n,m,a[101]; cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++) for(int j=m;j>=0;j--) if(f[j]!=0&&j+a[i]<=m)f[j+a[i]]+=f[j]; cout<<f[m]; return 0; } |
或者回溯
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 |
#include<iostream> #include<cstdio> using namespace std; int n,m; int a[10001],ans=0; bool used[10001]; void search(int k,int s) { if(s==m)ans++; if(s>=m)return; for(int i=k+1;i<=n;i++) { if(!used[i]) { used[i]=1; search(i,s+a[i]); used[i]=0; } } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&a[i]); search(0,0); printf("%d",ans); return 0; } |
Subscribe