题目链接: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]);
}
}
本文介绍如何使用动态规划解决HDU 5464问题,核心在于计算一系列数字中能组合成目标数值倍数的方案数量。通过定义dp数组并运用特定的状态转移方程实现。
453

被折叠的 条评论
为什么被折叠?



