# 一个用DP求解的问题的分析

17 + 5 + -21 + 15 = 16
17 + 5 + -21 - 15 = -14
17 + 5 - -21 + 15 = 58
17 + 5 - -21 - 15 = 28
17 - 5 + -21 + 15 = 6
17 - 5 + -21 - 15 = -24
17 - 5 - -21 + 15 = 48
17 - 5 - -21 - 15 = 18

We call the sequence of integers divisible by K if + or - operators can be placed between integers in the sequence in such way that resulting value is divisible by K. In the above example, the sequence is divisible by 7 (17+5+-21-15=-14) but is not divisible by 5.
You are to write a program that will determine divisibility of sequence of integers.

Input
There are multiple test cases, the first line is the number of test cases.
The first line of each test case contains two integers, N and K (1 ≤ N ≤ 10000, 2 ≤ K ≤ 100) separated by a space.

The second line contains a sequence of N integers separated by spaces. Each integer is not greater than 10000 by it's absolute value.

Output
Write to the output file the word "Divisible" if given sequence of integers is divisible by K or "Not divisible" if it's not.

Sample Input
2
4 7
17 5 -21 15
4 5
17 5 -21 15
Sample Output
Divisible
Not divisible

a1
/ \
a1-a2 a1+a2
/ \ / \
a1-a2-a3 a1-a2+a3 a1+a2-a3 a1+a2+a3
...................................

[code]
#include<iostream>
#include<string>
using namespace std;

int flag[10005][105];
int a[1005];
int n,K,N;
//@return 返回是否可以整除K,@parm level递归形成二叉数的层数,vaule为该层一个计算出节点的值
int f(int level,int value){
if(flag[level][value] != -1) return flag[level][value];//如果已经记录过了,就直接返回
int check,t1,t2;
t1 = (value + a[level]) % K;//进行+运算并对K取余数
t2 = (value - a[level]) % K;//进行-运算并对K取余数
t1 = t1 < 0 ? t1 + K : t1;//余数都改成正的
t2 = t2 < 0 ? t2 + K : t2;

if(level == N) check = (value % K == 0) ? 1 : 0;//如果第N层,递归出口,判断 value 是否可以整除K
else if(f(level + 1,t1) == 1) check = 1;//如果level + 1层计算结果可以整除K,则标记check为1,同时可以跳过另一个分支,因为0-a,0+a对最终判断否是否可以整除K的效果是一样的
else if( f(level + 1,t2) == 1 ) check = 1;
else check = 0;//左右分支均不可以整除 check=0;
return flag[level][value] = check;//返回并记录本层的check值
}

int main(){
int m;
int i,j;
string result;
cin >> n;
for(i = 0; i < n; i++){
cin >> N >> K;
for(j = 0; j < N; j++){
cin >> a[j];
if((a[j] %= K) < 0) a[j] += K;
}

for(j = 0; j <= N; j++)
for(m = 0; m <= K; m++)
flag[j][m] = -1;

result = f(1,a[0]) == 1 ? "Divisible" : "Not divisible" ;
cout << result << endl;
}
return 0;
}
[/code]