UVA - 10604 Chemical Reaction(6维dp+记忆化搜索)

来源:互联网 发布:股票收益率数据怎么找 编辑:程序博客网 时间:2024/05/27 19:26

题意:

有t组测试数据。每组测试数据开始有一个整数n,表示有n种试剂(最多6种)。接下来的n*n行,列出来了当前试剂和另外一种试剂混合产生的化合物以及放出的热量。
然后一个整数m,代表有m个试管(最多10个)。
接下来一行有m个数,表示m个试管里分别装了哪几种试剂。
问怎么组合能产生最少的热量。测试样例之间用/分开,结果用.表示

解析:

定义了六维的状态,dp[a][b][c][d][e][f];,表示剩下这么多试剂时,最小放出的热量。然后用记忆化搜索求解。

AC代码

#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <cstdlib>using namespace std;typedef long long ll;const int INF = 0x3f3f3f3f;const int N = 11;int dp[N][N][N][N][N][N];bool vis[N][N][N][N][N][N];int n;struct Date {    int res, h;}date[N][N];void init() {    memset(dp, 0, sizeof(dp));    memset(vis, false, sizeof(vis));}int dps(int a,int b,int c,int d,int e,int f) {    bool &flag = vis[a][b][c][d][e][f];    int &ans = dp[a][b][c][d][e][f];    if(flag) {        return ans;    }    ans = INF;    int t[7] = {0,a,b,c,d,e,f};    for(int i = 1; i <= 6; i++) {        for(int j = 1; j <= 6; j++) {            if(i == j && t[i] < 2) {                continue;            }            if(t[i] > 0 && t[j] > 0) {                t[i]-- , t[j]--;                t[date[i][j].res]++;                int sum = dps(t[1],t[2],t[3],t[4],t[5],t[6]);                ans = min(ans, sum + date[i][j].h);                t[i]++ , t[j]++;                t[date[i][j].res]--;            }        }    }    flag = true;    return ans = (ans == INF ? 0 : ans);}int main() {    int T ,k;    int tmp;    scanf("%d",&T);    while(T--) {        init();        scanf("%d", &n);        for(int i = 1; i <= n; i++) {            for(int j = 1; j <= n; j++) {                scanf("%d%d", &date[i][j].res , &date[i][j].h);            }        }        int tubes[7];        memset(tubes, 0, sizeof(tubes));        scanf("%d", &k);        for(int i = 1; i <= k; i++) {            scanf("%d", &tmp);            tubes[tmp]++;        }        char cmd[5];        scanf("%s",cmd);        int ans = dps(tubes[1],tubes[2],tubes[3],tubes[4],tubes[5],tubes[6]);        printf("%d\n",ans);    }    return 0;}
0 0
原创粉丝点击