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;
}
相关文章
相关标签/搜索