题意:
有 n 个数..在它们之间放入 + - * /
问最后可不可以被 k 整除..
思路:
用数组dp[ tmp ][ j ] tmp 表示当前状态和前一个状态<用到了滚动数组>.. j 表示当前值对 k 取模是否可行..
如果 dp[tmp][j] 是true..那dp[ tmp ][( j%k + a[i]%k)%k] 也是可行的~
所以数组标记为 true/false 就好..
最后看dp[tmp][0] 是否为true..就知道结果了..
Code:
#include <stdio.h>
#include <cstring>
#include <fstream>
#define get(x) x>0?(x)%k:(-(x))%k
int main()
{
int i, j;
int tmp, tmp1;
// freopen("e:\\acm\\mess\\stdin-stdout\\in.txt", "r", stdin);
// freopen("e:\\acm\\mess\\stdin-stdout\\out.txt", "w", stdout);
int n, k, a[11110];///!!! promise the ans of mod is correct, because n is 10000 while k is 100
bool dp[2][110];
while(scanf("%d %d", &n, &k) != EOF)
{
for(i = 0; i < n; ++i)
scanf("%d", &a[i]);
///***DP***///
for(i = 0; i < k; ++i) dp[0][i] = false;
dp[0][get(a[0])] = true; ///mod a[0] is true
tmp = 1, tmp1 = 0;
for(i = 1; i < n; ++i){
tmp = !tmp, tmp1 = !tmp1;
for(j = 0; j < k; ++j) dp[tmp1][j] = false;
for(j = 0; j < k; ++j)
if(dp[tmp][j]) dp[tmp1][get(j+a[i])] = dp[tmp1][get(j-a[i])] = true;
}
if(dp[tmp1][0]) printf("Divisible\n");
else printf("Not divisible\n");
}
return 0;
}
define 一个函数get() 就可以直接用了~比较方便~
这道题类DP..根据上一个结果推出后一个结果..
初始条件:dp[0][a[0]] = true, dp[0][else] = false
动态转移方程: if(dp[tmp][j]) dp[tmp1][get(j+a[i])] = dp[tmp1][get(j-a[i])] = true;
结果: dp[1][0]