UVA - 10604 Chemical Reaction

题目大意:给出n和m,有n种化学药剂,型号由1~n,然后给出n * n行代表相应的两种化学药剂反应后的生成物以及释放的热量,然后给出m个试管,每种试管中有对应的药剂,要求将m种药剂反应合成一种,不要求反应后药剂的种类,要求反应所散发的热量最少。


注意:i和j反应可能与j和i反应不同,反应可能吸热,每组测试以/结束。


解题思路:开一个cnt数组记录每种药剂的数量,然后用递归的方法遍历所有的情况,并且要记录相同的子情况。


#include <cstdio>
#include <cmath>
#include <cstring>
#include <climits>
using namespace std;

int m, k, DP[2000010], A[8][8][2];

int DPS(int x) {
	if (DP[x] != -1)
		return DP[x];
	DP[x] = INT_MAX;
	for (int i = 0; i < m; i++) {
		for (int j = 0; j < m; j++) {
			if (x / ((int)pow(11.0, i)) % 11 == 0 || x / ((int)pow(11.0, j)) % 11 == 0)
				continue;
			if (i == j && x / ((int)pow(11.0, i)) % 11 < 2)
				continue;
			if (DP[x] > DPS(x - pow(11.0, i) - pow(11.0, j) + pow(11.0, A[i][j][0]-1)) + A[i][j][1])
				DP[x] = DPS(x - pow(11.0, i) - pow(11.0, j) + pow(11.0, A[i][j][0]-1)) + A[i][j][1];
		}
	}
	return DP[x];
}

int main() {
	int T;
	scanf("%d", &T);
	while (T--) {
		memset(DP, -1, sizeof(DP));
		scanf("%d", &m);
		for (int i = 0; i < m; i++)
			for (int j = 0; j < m; j++)
				scanf("%d%d", &A[i][j][0], &A[i][j][1]);
		scanf("%d", &k);
		int dst = 0;
		for (int i = 0; i < k; i++) {
			int temp; 
			scanf("%d", &temp);
			dst = dst + pow(11.0, temp - 1);
		}

		for (int i = 0; i < m; i++)
			for (int j = 0; j < 11; j++)
				DP[(int)(pow(11.0,i)*j)] = 0;
		printf("%d\n", DPS(dst));
		scanf("%*s");
	}
	return 0;
}


你可能感兴趣的:(UVA - 10604 Chemical Reaction)