Luogu P1356 【数列的整数性】题解

对于什么模什么整除之类的DP题我总是很慌张

但是像我这种蒟蒻都过了这道题是不是?

对于这种能否整除的DP题目,我们只需要考虑前i个数通过一定的组合,mod k 能否 == j,
这就是我们要写的`状态`

bool f[i][j]表示能否通过一定的组合将前i个数 mod k = j;

显而易见,最后的答案是能否通过一定的组合将前n个数 mod k = 0
也就是f[n][0]是否为true;

当状态为f[i][j]时,若状态f[i][(j +- a[i] % k + k) % k] 为true,则f[i][j]也一定为true;+-里只要满足一个就可以了,所以要用||符号

最后头疼的是边界条件,卡了我很久

f[1][(a[1] % k + k) % k] = f[1][(-a[1] % k + k) % k] = true;

#include <bits/stdc++.h>
using namespace std;

int t,n,k;
bool f[10000 + 10][100 + 10];
int a[10000 + 10];

int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&k);
        memset(f,0,sizeof(f));
        for(int i = 1;i <= n; i++) scanf("%d",&a[i]);
        f[0][0] = 1;
        f[1][(a[1] % k + k) % k] = f[1][(-a[1] % k + k) % k] = true;
        for(int i = 2;i <= n; i++){
            for(int j = 0;j < k; j++){
                f[i][j] = (f[i - 1][((j + a[i] % k) + k) % k]) || (f[i - 1][(j - a[i] % k + k) % k]);
            }
        }
        printf("%s\n",f[n][0] == 1 ? "Divisible" : "Not divisible");
    }
    return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/chloristendika/p/9240924.html