本题的动态转移思路是什么?

原题链接:http://noi.openjudge.cn/ch0206/3531。

解释
一个给定的正整数序列,在每个数之前都插入+号或-号后计算它们的和。序列:1、2、4共有8种可能的序列。
所有结果中至少有一个可被整数k整除,我们则称此正整数序列可被k整除。例如上述序列可以被3、5、7整除,而不能被2、4、6、8……整除。注意:0、-3、-6、-9……都可以认为是3的倍数。

输入
输入的第一行包含两个数:N(2 < N < 10000)和k(2 < k< 100),其中N代表一共有N个数,k代表被除数。第二行给出序列中的N个整数,这些整数的取值范围都0到10000之间(可能重复)。

输出
如果此正整数序列可被k整除,则输出YES,否则输出NO。

样例数据
输入
3 2
1 2 4
输出
NO

说下思路吧,就不写代码了。
用dp[i][j]表示前i个数组成的序列除k,余数为j是否成立。最后只用判断dp[n][0]是否为1就可以了。
递推式:dp[i][j]是否为真,取决a[i]对结果的影响。如果dp[i][j]=1,那么存在一个和为x,使得x%k=j。假设前i-1个数列为y,则y=x+a[i]ory=x-a[i]. 根据x%k=j,可以得到y%k=(x+a[i])%k=(x%k+a[i]%k)%k=(j+a[i]%k)%k,或者y%k=(x-a[i])%k=(x%k-a[i]%k)%k=(j-a[i]%k)%k.
所以就有递推式:dp[i][j]=(dp[i-1][(j+a[i]%k)%k])||(dp[i-1][(j-a[i]%k)%k])
为了严谨一点,(j+a[i]%k)%kand(j-a[i]%k)%k可能为负,都取个绝对值
最后写成dp[i][j]=(dp[i-1][abs((j+a[i]%k)%k)])||(dp[i-1][abs((j-a[i]%k)%k)])
最后初始化dp[0][0]=1,如果不用递归的话,来个循环i [1,n],j [0,k-1]递推就可以了