Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 11001 | Accepted: 3933 |
Description
Input
Output
Sample Input
4 7 17 5 -21 15
Sample Output
Divisible
题意就是给了N个数,在N-1个位置变换+ -号,问得到的结果中有没有能够整除K的,如果有,输出Divisible。没有,输出Not Divisible。
DP真是一片很深的海。
越做DP越觉得DP的花样很多,这个是我做了POJ1837觉得DP是可以做这道题的。觉得DFS也应该可以,没试。。。
POJ1837和这道题都是固定枚举其中的某个状态或者变量,这里的可以枚举的状态就是余数,给了K,所以我只需对0到K-1这些余数做枚举,然后从i的余数状态推i+1的余数状态。
就是这样:
dp[i][(j+value[i])%mod] +=dp[i-1][j];
dp[i][(j-value[i]+mod)%mod] +=dp[i-1][j];
然后这样做可能是因为数目比较大了溢出还是怎样WA了一次,于是我控制了一下数值。这样:
dp[i][(j+value[i])%mod] +=dp[i-1][j];
dp[i][(j-value[i]+mod)%mod] +=dp[i-1][j];
if(dp[i][(j+value[i])%mod]>10)
dp[i][(j+value[i])%mod]=10;
if(dp[i][(j-value[i]+mod)%mod]>10)
dp[i][(j+value[i])%mod]=10;
。。。很幼稚的方法,但还是涨姿势长见识了。。。
代码:
#include <iostream> #include <algorithm> #include <cmath> #include <vector> #include <string> #include <cstring> using namespace std; int num,mod; int dp[10005][102]; int value[10005]; int main() { int temp,i,j; cin>>num>>mod; cin>>value[1]; value[1]=abs(value[1])%mod; for(i=2;i<=num;i++) { cin>>temp; value[i]=abs(temp); value[i]=value[i]%mod; } memset(dp,0,sizeof(dp)); dp[1][value[1]]=1; for(i=2;i<=num;i++) { for(j=0;j<mod;j++) { dp[i][(j+value[i])%mod] +=dp[i-1][j]; dp[i][(j-value[i]+mod)%mod] +=dp[i-1][j]; if(dp[i][(j+value[i])%mod]>10) dp[i][(j+value[i])%mod]=10; if(dp[i][(j-value[i]+mod)%mod]>10) dp[i][(j+value[i])%mod]=10; } } if(dp[num][0]) { cout<<"Divisible"<<endl; } else { cout<<"Not divisible"<<endl; } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
POJ 1745:Divisibility 枚举某一状态的DP
原文地址:http://blog.csdn.net/u010885899/article/details/47284347