@@ -15,61 +15,47 @@ typedef vector<vi> vvi;
15
15
typedef vector<string> vs;
16
16
typedef vector<vs> vvs;
17
17
#define inf 1000000000
18
- int D[20 ];
19
- int M[20 ][20 ];
20
- int n;
21
-
22
- struct node {
23
-
24
- int state;
25
- int cost;
26
- node (int s, int c) : state(s), cost(c) {}
27
- };
28
-
29
- bool operator <(node a, node b){
30
- return a.cost > b.cost ;
31
- }
32
18
33
19
class KiloManX {
34
- public:
20
+ public:
21
+ vs d;
22
+ vi h;
23
+ int n;
24
+ map<int , int > best;
35
25
36
- int leastShots (vs damageChart, vi bossHealth)
37
- {
38
- map<int , int > H;
39
- n = bossHealth.size ();
40
- for (int i = 0 ; i <= n; i++)
41
- for (int j = 0 ; j <= n; j++)
42
- M[i][j] = inf;
43
- for (int i = 1 ; i <= n; i++) M[0 ][i] = bossHealth[i-1 ];
44
- for (int i = 1 ; i <= n; i++)
45
- for (int j = 1 ; j <= n; j++){
46
- int k = damageChart[i-1 ][j-1 ] - ' 0' ;
47
- if (k) M[i][j] = (bossHealth[j-1 ] + k - 1 )/k;
48
- }
49
- priority_queue<node> Q;
50
- for (int i = 1 ; i <= n; i++){
51
- H[(1 <<i)+1 ] = M[0 ][i];
52
- Q.push (node ((1 <<i)+1 , M[0 ][i]));
26
+ int dp (int s){
27
+ // If state s is already cached return it
28
+ if (best.count (s)) return best[s];
29
+ // Final state makes zero contribution
30
+ if ( s == ((1 <<n) - 1 ) ) return 0 ;
31
+ // minj is minimum shots to transition to some state j
32
+ int minj = inf;
33
+ for (int j = 0 ; j < n; j++){
34
+ // If j is not shot
35
+ if ( !(s & (1 <<j) ) ){
36
+ // mini is minimum shots required to shoot j from some weapon i
37
+ int mini = h[j];
38
+ for (int i = 0 ; i < n; i++){
39
+ int k = d[i][j] - ' 0' ;
40
+ // if i can shoot j
41
+ if (i == j || !(s & (1 <<i) ) || k == 0 ) continue ;
42
+ mini = min (mini, (h[j]+k-1 )/k );
43
+ }
44
+ minj = min (minj, mini + dp ( s|(1 <<j) ) );
53
45
}
54
- while (!Q.empty ()){
55
- node p = Q.top ();
56
- Q.pop ();
57
- int s = p.state , c = p.cost , m = inf;
58
- if (s == (1 <<(n+1 ))-1 ) return c;
59
- for (int i = 0 ; i <= n; i++)
60
- for (int j = 1 ; j <= n; j++)
61
- if (s&(1 <<i) && !(s&(1 <<j)) && M[i][j] < inf){
62
-
63
- m = M[i][j];
64
- int t = (s|(1 <<j));
65
- if (H.count (t) == 0 || H[t] > c+m){
66
- H[t] = c+m;
67
- // cout<<"node <"<<i<<","<<j<<"> with value "<<m<<" pushed into queue at value "<<c<<endl;
68
- Q.push (node (t, c+m));
69
- }
70
- }
71
- }
72
46
}
47
+ best[s] = minj;
48
+ return minj;
49
+ }
50
+
51
+ int leastShots (vs damageChart, vi bossHealth)
52
+ {
53
+ n = bossHealth.size ();
54
+ d = damageChart;
55
+ h = bossHealth;
56
+ best.clear ();
57
+ return dp (0 );
58
+ }
73
59
74
60
// BEGIN CUT HERE
75
61
public:
0 commit comments