当前位置: 代码迷 >> 综合 >> BestCoder Round #56 Clarke and problem
  详细解决方案

BestCoder Round #56 Clarke and problem

热度:41   发布时间:2023-12-06 03:29:56.0

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5464

题意:给我们n个数以及p,问我们从中间取出一些数使得和为p的倍数的方法数,我们可以采用DP来解决这个问题

dp[i][j]表示取到第i个数和对p取模为j的方案数,状态转移方程为:dp[i][j] = dp[i-1][j] + dp[i-1][(j-(a[i]%p+p)%p)];

小编解释一下这个状态转移方程,取到第i个数和对p取模为j的方案数 = 取到第i-1个数和对p取模为j的方案数 + 取到第i-1个数和加上a[i]后对p取模为j的方案数。我们最后需要的就是dp[n][0];

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL __int64
const int maxn = 1005;
const LL MOD = 1000000007;
LL dp[maxn][maxn],a[maxn];
int main()
{int T;scanf("%d",&T);while(T--){int n,p;scanf("%d%d",&n,&p);memset(dp,0,sizeof(dp));for(int i=1; i<=n; i++)scanf("%I64d",&a[i]);dp[0][0] = 1;for(int i=1; i<=n; i++)for(int j=0; j<p; j++){LL tmp = (j - (a[i]%p) + p)%p;dp[i][j] = (dp[i-1][tmp]+dp[i-1][j])%MOD;}printf("%I64d\n",dp[n][0]);}
}


  相关解决方案