forked from daniCh8/eth-algolab-2019
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcorbusier.cpp
35 lines (31 loc) · 1.2 KB
/
corbusier.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
* This solution is made through a bottom-up dp. The memory is a [n*k] boolean matrix that stores in a cell memo[i][j] whether or not
* it's possible to build a tower of disks that have a height congruent to j using only disks from 0 to i.
* memo[i][j] = (memo[i-1][j] because if it was possible with disks from 0 to i-1, it's also possible with disks from 0 to i
* || memo[i-1][(j-disk[i]+k)%k] because if I can reach the modulo j-disk[i] without disk[i], I just need to add the latter to have modulo j
* || disk[i] == j because I would take that disk only)
* The answer is then whether memo[n][i] is true or not.
**/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
ios_base::sync_with_stdio(false);
int t;
cin >> t;
while(t--){
int n, i, k;
cin >> n >> i >> k;
vector<int> disks(++n, 0);
for(int j = 1; j < n; j++) {
cin >> disks[j];
disks[j] %= k;
}
vector<vector<bool>> memo(n, vector<bool>(k, false));
for(int r = 1; r < n; r++)
for(int c = 0; c < k; c++)
memo[r][c] = (disks[r] == c || memo[r-1][c] || memo[r-1][(c-disks[r]+k)%k]);
memo[n-1][i] ? cout << "yes\n" : cout << "no\n";
}
}