Description
给出一个长度为
t
的序列
Input
第一行三个整数
n,m,t
,之后输入
t
个整数
Output
输出满足条件的序列个数,结果模 109+7
Sample Input
7 6 5
5 4 12 6 5
Sample Output
6
Solution
首先只需考虑
ai
模
m
的余数,同余的两个数字不能同时出现(一个配
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
#include<bitset>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=123;
#define mod 1000000007
bitset<maxn>s[7];
int n,m,t,num[maxn],a[11];
int dfs(int cnt,int pos)//已经拿了cnt个邮箱,从体积为pos的邮箱开始抉择是否拿
{
int ans=1;
for(int i=0;i<cnt;i++)ans=(ll)ans*num[a[i]]%mod;
if(cnt<6)
{
for(int i=pos;i<=m/2;i++)
{
if(!num[i]||s[cnt][i]||s[cnt][m-i])continue;
a[cnt]=i;
s[cnt+1]=s[cnt];
s[cnt+1]|=s[cnt]<<i;
s[cnt+1]|=s[cnt]>>i;
s[cnt+1]|=s[cnt]<<(m-i);
s[cnt+1]|=s[cnt]>>(m-i);
ans+=dfs(cnt+1,i+1);
if(ans>=mod)ans-=mod;
}
}
return ans;
}
int main()
{
scanf("%d%d%d",&n,&m,&t);
while(t--)
{
int x;
scanf("%d",&x);
x%=m;
x=min(x,m-x);
num[x]++;
}
s[0][0]=1;
printf("%d\n",dfs(0,1));
return 0;
}