uva10604(DP +回溯)

来源:互联网 发布:能查高数题的软件 编辑:程序博客网 时间:2024/04/28 07:19

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

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

给出有几种药剂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
原创粉丝点击