uva10604(DP +回溯)

题目的意思就是有几种化学药剂;

两种药剂反应会放出热量,并且生成一种药剂;

给出有几种药剂m.

然后是按顺序给出反应的结果.

第一种药剂 和 第一种药剂反应 生成哪种药剂 ,放出多少热量

第一种药剂 和 第二种药剂....

.....(一共m*m)行;

然后给出药剂的药量.一共有k瓶.

每瓶分别是什么..

问反应到只剩一瓶药剂为止,最小的放热.

用一个六维数组,保存6种药剂剩下多少瓶,最小放热.

然后每次都遍历可以反应的药剂,找最小值.


AC代码;


#include<stdio.h>
#include<string.h>
const int INF = 0x3f3f3f3f;
const int N = 10;
int f[N][N][N][N][N][N];
int m;
int n;
int num[N];
struct st {
	int c;
	int h;
}s[N][N];
int min(int a , int b) {
	return a < b ? a : b;
}
int dp(int total) {
	int& cur = f[num[1]][num[2]][num[3]][num[4]][num[5]][num[6]];
	if(cur != -1)
		return cur;
	if(total == 1) {
		return 0;
	}
	cur = INF;
	for (int i = 1 ; i <= m ; i++) {
		for (int j = 1; j <= m ; j++) {
			if(i == j && num[i] < 2)
				continue;
			if(num[i] > 0 && num[j] > 0) {
				num[i]--;
				num[j]--;
				num[s[i][j].c]++;
				cur = min(cur , dp(total - 1) + s[i][j].h);
				num[i]++;
				num[j]++;
				num[s[i][j].c]--;
			}
		}
	} 
	return cur;
}
int main () {
	int t;
	scanf("%d",&t);
	while(t--) {
		memset(f , -1 ,sizeof(f));
		memset(num , 0 ,sizeof(num));
		scanf("%d",&m);
		for (int i = 1 ; i <= m ; i++) {
			for (int j = 1; j <= m ;j++) {
				scanf("%d%d",&s[i][j].c,&s[i][j].h);
			}
		}
		scanf("%d",&n);
		while(n--) {
			int k;
			scanf("%d",&k);
			num[k]++;
		}	
		int total = num[1] + num[2] + num[3] + num[4] + num[5] + num[6] ;
		printf("%d\n",dp(total));
		char a[10];
		scanf("%s",a);
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值