poj 1745 Divisibility

題目描述:ios

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.express

Inputide

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.lua

Outputspa

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

Sample Inputorm

4 7
17 5 -21 15

Sample Outputci

Divisible
題目大概的意思就是:給定一連串的數字,可能爲正可能爲負,相鄰的兩個數之間,能夠添加+或者-操做符,所以,這一串連續數字的和,就有不少個,如今給你一個k,讓你判斷可否在這一連串的數字之間,
加入+或者—操做,使獲得的和對k求餘等於0,若是能,輸出Divisible,若是不能,輸出Not divisible.
首先,咱們假設A1到An之間,經過添加+或者-操做符獲得和對k求餘的餘數爲Rn,A1到An-1之間,經過添加+或者-操做符獲得的對k求餘的餘數爲Rn-1,那Rn-1和Rn之間有什麼聯繫呢?
Rn=(Rn-1 + An)%k,Rn=(Rn-1 - An)%k;
到了這一步,相信很對人都看出來了,這題要用到DP.下面咱們來看下DP的狀態轉移方程吧.
咱們定義dp[i][j]表示前i個數的和對k求餘的餘數是否能夠爲j(即dp[i][j]是個bool變量)
那咱們怎麼來求dp[i][j]呢?
首先,咱們得判斷dp[i-1][j]是否爲真,若是爲真,就說明了前i-1個數的某個和(和有多種可能)對k求餘,餘數爲j,
爲此,咱們就能夠推出dp[i][(j+Ai)%k]=true,dp[i][j-Ai)%k]=true;
但有個問題是,這一連串的數字中有負數,若是他們的和加起來爲負數,那麼餘數就有多是負數,那就有問題了.
一個數對k(k>0)求餘,可能的值落在[-k+1,k-1]之間,而咱們只能處理[0,k-1]之間,能不能把[-k+1,0]的這一部分轉換成[0,k-1],實際上是能夠的,(m%k+k)%k就恰好把負的那一部分轉換爲了正的,這樣咱們
就能夠用dp去求解了,下面附上代碼:
#include<iostream>
#include<cstring>
using namespace std;
#define MAXN 10005
bool dp[MAXN][100];
int main()
{
    int n,k,temp;
    memset(dp,false,sizeof(dp));
    cin >> n >> k >> temp;
    dp[1][(temp%k+k)%k] =true;
    for(int i=2;i<=n;++i)
    {
        cin >> temp;
        for(int j=0;j<k;++j)
        {
            if(dp[i-1][j])
            {
                dp[i][((j+temp)%k+k)%k]=true;
                dp[i][((j-temp)%k+k)%k]=true;
            }
        }
    }
    if(dp[n][0])
    {
        cout << "Divisible" << endl;
    }
    else
    {
        cout << "Not divisible" << endl;
    }
    return 0;
}
相關文章
相關標籤/搜索