POJ1745Divisibility(dp)

Zhac發表於2016-08-09
Description
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.
Input
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.
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
4 7
17 5 -21 15
Sample Output

Divisible

題意:給你n個數,每兩個數之間你可以任意加減,求的每個和中是否有和可以對k整除,如果有輸出Divisible,否則輸出Not divisible

思路:這道題直接一個二維陣列算出所有的結果在判斷是不現實的。所以我們可以簡化為dp[i][j],找前i個數加減後 對k整除=j是對的。層層推直到最後一個,最後判斷dp[n][0]是否成立就可以了。

狀態轉移方程

當dp[i-1][j]非0時

1,dp[i][t] = 1其中t = ((j + a[i]) % K + K) % K. 說明一下——(j + a[i])%K後 加個K最後再取餘 是為了避免值是負數。

2,dp[i][t] = 1其中t = ((j - a[i]) % K + K) % K.


程式碼:

#include<stdio.h>
#include<iostream>
using namespace std;
bool dp[10001][101];
long long  num[10001];
int main()
{
	int n,k;
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++)
	{
		int a;
		scanf("%d",&a);
		num[i]=a%k;
	}
	dp[0][0]=true;
 for(int i=1;i<=n;i++)
 {
	 	 for(int j=k-1;j>=0;j--)
		 if(dp[i-1][j])
		 {
			 dp[i][((j+num[i])%k+k)%k]=1;
			 dp[i][((k+j-num[i])%k+k)%k]=1;
		 }
 }
 if(dp[n][0])
	 printf("Divisible\n");
 else
	 printf("Not divisible\n");
return 0;
}