给定N个数,选出任意多的数(每个数只能选一次),使其和为M的整数倍。问最少需要选几个数。
标签:blog http io ar os sp for div on
给定N个数,选出任意多的数(每个数只能选一次),使其和为M的整数倍。问最少需要选几个数。
第一行输入一个数T代表测试用例组数(T<=10),接下来T组测试用例,每组测试用例第一行为整数M, N(1<=M, N<=1000);接下来N行每行一个数,分别代表N个数之一。
对于每组测试用例,输出满足条件最少需要选几个数,若没有解输出-1。每行输出一个结果。
2
4 3
1
1
1
2 2
2
4
-1
1
oooooorz 苑神 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<cstdlib> #include<queue> #include<vector> #include<set> using namespace std; int t,m,n,dp[1010],a[1010],sign[1010][1010],temp; #define inf 2000000000 int main() { scanf("%d",&t); while(t--) { memset(dp,0,sizeof(dp)); memset(a,0,sizeof(a)); memset(sign,0,sizeof(sign)); scanf("%d%d",&m,&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=0;i<m;i++) dp[i]=inf; for(int i=1;i<=n;i++) { dp[a[i]%m]=1; sign[a[i]%m][i]=1; } for(int i=0;i<m;i++) { for(int j=1;j<=n;j++) { temp=(i+a[j])%m; if(sign[i][j]==0&&dp[temp]>dp[i]+1) { dp[temp]=dp[i]+1; for(int k=0;k<n;k++) sign[temp][k]=sign[i][k]; sign[temp][j]=1; } } } if(dp[0]==inf) printf("-1\n"); else printf("%d\n",dp[0]); } return 0; }
标签:blog http io ar os sp for div on
原文地址:http://www.cnblogs.com/a972290869/p/4099603.html