1745:Divisibility
-
总时间限制:
- 1000ms 内存限制:
- 65536kB
-
描述
-
Consider an arbitrary sequence of integers. One can place + or - operators between integers in the sequence, thus deriving different arithmetical expressions that evaluate to different values. Let us, for example, take the sequence: 17, 5, -21, 15. There are eight possible expressions: 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.
输入
-
The first line of the input file 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.
输出
- Write to the output file the word "Divisible" if given sequence of integers is divisible by K or "Not divisible" if it's not. 样例输入
-
4 7 17 5 -21 15
样例输出
-
Divisible
-
tips:N达到了1000级别;暴力枚举=暴力悲剧;
-
dp[i][j]代表前i个数字经过运算 取余k 的结果 能否为 j;
-
因为取余可能为负,我们一开始做了绝对值处理;取余过程中出现的负数我们都转化为正数进行处理;
-
动态转移方程:dp[i][(j+a[i])%k]=true,dp[i][((j-a[i])%k+k)%k]=true; dp[i-1][j]=true;
-
#include<iostream> #include<cstring> #include<cmath> using namespace std; int n,k; int a[11112]; bool dp[11000][111]; //dp[i][j]表示前i个数能否对k取余得到j int main() { memset(dp,false,sizeof(false)); cin>>n>>k; for(int i=1;i<=n;i++)cin>>a[i],a[i]=abs(a[i])%k; dp[1][a[1]]=true; for(int i=2;i<=n;i++) { for(int j=0;j<k;j++) if(dp[i-1][j]){ dp[i][((j-a[i])%k+k)%k]=true; dp[i][(j+a[i])%k]=true; } } if(dp[n][0])cout<<"Divisible"<<endl; else cout<<"Not divisible"<<endl; return 0; }