@@ -15,61 +15,47 @@ typedef vector<vi> vvi;
1515typedef vector<string> vs;
1616typedef vector<vs> vvs;
1717#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- }
3218
3319class KiloManX {
34- public:
20+ public:
21+ vs d;
22+ vi h;
23+ int n;
24+ map<int , int > best;
3525
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) ) );
5345 }
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- }
7246 }
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+ }
7359
7460// BEGIN CUT HERE
7561 public:
0 commit comments