给定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