將前n-1個數看成一個整體序列,則n個數可能產生的結果就等於“前n-1個數產生的所有結果分別加上第n個數或分別減去第n個數”
n-2也同理……直到1為止。
由於是判斷有無結果能被k整除,所以所有的中間結果都可以取余k,從而使所有可能的結果保持在一個不大的范圍,用數組進行存儲。
下面代碼中的ans[i][j]表示i個數的序列有沒有取余k后為j的結果,0表示沒有,1表示有。
1 #include<iostream> 2 using namespace std; 3 4 const int N=105; 5 int a[N*N],ans[N*N][N]; 6 7 int main(){ 8 int n,k; 9 //接收輸入 10 cin>>n>>k; 11 for(int i=1;i<=n;i++){ 12 cin>>a[i]; 13 a[i]%=k; 14 } 15 ans[0][0]=1; 16 //核心算法 17 for(int i=1;i<=n;i++){ 18 for(int j=0;j<k;j++){ 19 if(ans[i-1][j]){ 20 ans[i][(j+a[i])%k]=ans[i][(j-a[i]+k)%k]=1; 21 } 22 } 23 } 24 if(ans[n][0])cout<<"YES"; 25 else cout<<"NO"; 26 return 0; 27 }