Dream | ||||||
| ||||||
Description | ||||||
Dream是一个很好玩的学姐。虽然外表看起来有点伪学长,但是实际上还是个很爱玩很可爱的女生。有一次她的小学妹问了她一个问题:“学姐,这里有一些数,17,5,-21,16。如果往里面放入加号或减号后,结果能不能被7整除吖~?” 在可爱的小学妹面前,Dream的小宇宙瞬间爆发~Dream:“行~等一下,我帮你算一算。” 聪明的Dream很快就算出来,17 + 5 + -21 - 15 = -14。这样就可以被7整除了! “那这些数呢,能不能被k整除吖?” 小学妹递给Dream一本写满数字的本子。 Dream瞬间头大,你能帮助喜欢小学妹的Dream解决这个问题吗~? | ||||||
Input | ||||||
本子上有很多组数。 每组数的第一行有两个数:n和k。(1 <= n <= 10000, 2 <= k <= 100)表示有n个数,问能否被k整除。 第二行有n个数,每个数的绝对值都不大于10000. | ||||||
Output | ||||||
如果能够被n个数的最终计算结果整除就输出”DreamV5”,否则输出”Orz..” | ||||||
Sample Input | ||||||
4 7 17 5 -21 15 | ||||||
Sample Output | ||||||
DreamV5 | ||||||
Source | ||||||
2013 Summer Holiday Summarize |
题目大意:
给你N个数,和一个mod值K.
让你给这N个数前边加上+或者是-.求最终的和是否能被k整除。
思路:
1、观察到K并不是很大,那么设定dp【i】【j】表示dp到第i个数,%k的值为j的方案是否存在。
2、那么有状态转移方程:
注意和可能为负数,负数取模变成正数的方法就是先对和取模,然后+mod,再%mod.
Ac代码:
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int a[10500];
int dp[10500][550];
int main()
{
int n,mod;
while(~scanf("%d%d",&n,&mod))
{
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=1;i<=n;i++)
{
for(int j=0;j<mod;j++)
{
if(dp[i-1][j]>0)
{
dp[i][((j+a[i])%mod+mod)%mod]=max(dp[i][((j+a[i])%mod+mod)%mod],dp[i-1][j]);
dp[i][((j-a[i])%mod+mod)%mod]=max(dp[i][((j-a[i])%mod+mod)%mod],dp[i-1][j]);
}
}
}
if(dp[n][0]>0)printf("DreamV5\n");
else printf("Orz..\n");
}
}