TopCoder SRM 344 Div1 Medium QuantumAlchemy

問題

A〜Zのアルファベットで表される物質がある。
最初initialで表される物質を持っている。


錬金反応を何度か起こして物質Xを作りたい。
錬金反応は最低何回起こさなければならないか、求めよ。


錬金反応は、
原料の物質->目的の物質の形式で与えられる。
原料の物質は必ず二つ以上であり、ある1種類の目的の物質を作る反応は高々一つしかない。

制約条件

initialの大きさは50以下

方針

Xから逆に探索していく。


X<-ABCだったとき、初期状態で持っていない物質があれば、その物質は必ず作らなくてはならない。
そのため、起こさなければならない反応が一意に定まる。
したがって、貪欲に起こすべき反応を探していけばよい。


必要な物質の合計が50個を超えたら、その時点でXを作れないことは確定するので、シミュレーションを打ち切ってよい。

ソースコード

class QuantumAlchemy {
  public:
  int minSteps(string initial, vector <string> reactions) {
		
		vi v(26), init(26);
		v['X' - 'A']++;
		rep(i, initial.size()) init[initial[i] - 'A']++;
		
		vector<vi> reac(26);
		rep(i, reactions.size()){
			int p = reactions[i].find("-");
			string s = reactions[i].substr(0, p);
			string t = reactions[i].substr(p + 2);
			
			vi tmp(26);
			rep(j, s.size()) tmp[s[j] - 'A']++;
			reac[t[0] - 'A'] = tmp;
		}
		
		int ans = 0, sz = 1;
		while(1){
			bool update = 0;
			rep(i, 26) if(v[i] > init[i]){
				if(reac[i].empty()) return -1;
				v[i]--;
				sz--;
				rep(j, 26) v[j] += reac[i][j], sz += reac[i][j];
				update = 1;
				break;
			}
			if(!update) break;
			if(sz > 50) return -1;
			ans++;
		}
		return ans;
  }
};