Clarke and problem
问题描述
克拉克是一名人格分裂患者。某一天,克拉克分裂成了一个学生,在做题。 突然一道难题难到了克拉克,这道题是这样的: 给你nn个数,要求选一些数(可以不选),把它们加起来,使得和恰好是pp的倍数(00也是pp的倍数),求方案数。 对于nn很小的时候,克拉克是能轻易找到的。然而对于nn很大的时候,克拉克没有办法了,所以来求助于你。
输入描述
第一行一个整数T(1 \le T \le 10)T(1≤T≤10),表示数据的组数。 每组数据第一行是两个正整数n, p(1 \le n, p \le 1000)n,p(1≤n,p≤1000)。 接下来的一行有nn个整数a_i(|a_i| \le 10^9)a?i??(∣a?i??∣≤10?9??),表示第ii个数。
输出描述
对于每组数据,输出一个整数,表示问题的方案数,由于答案很大,所以求出对10^9+710?9??+7的答案即可。
输入样例
1 2 3 1 2
输出样例
2
Hint
有两种方案:什么也不选;全都选。 一眼dp
//1085422276 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<queue> #include<cmath> #include<map> #include<bitset> #include<set> #include<vector> #include<stack> using namespace std ; typedef long long ll; #define mem(a) memset(a,0,sizeof(a)) #define meminf(a) memset(a,127,sizeof(a)); #define memfy(a) memset(a,-1,sizeof(a)) #define TS printf("111111\n"); #define FOR(i,a,b) for( int i=a;i<=b;i++) #define FORJ(i,a,b) for(int i=a;i>=b;i--) #define READ(a,b) scanf("%d%d",&a,&b) #define mod 1000000007 #define maxn 1501 inline ll read() { ll x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘) { if(ch==‘-‘)f=-1; ch=getchar(); } while(ch>=‘0‘&&ch<=‘9‘) { x=x*10+ch-‘0‘; ch=getchar(); } return x*f; } //**************************************** ll dp[1001][2005]; ll n,p,a[maxn]; int main() { int T=read(); while(T--) { mem(dp); n=read(); p=read(); FOR(i,1,n) { a[i]=read(); if(a[i]<0) a[i]=(a[i]%p+p)%p; else a[i]=a[i]%p; } dp[0][0]=1; for(int i=1;i<=n;i++) { for(int j=0;j<p;j++) { dp[i][j]=(dp[i][j]+dp[i-1][j])%mod; dp[i][(a[i]+j)%p]=(dp[i][(a[i]+j)%p]+dp[i-1][j])%mod; } } cout<<(dp[n][0])%mod<<endl; } return 0; }
代码
时间: 2024-10-12 11:41:44