uva_10604 - Chemical Reaction( Hash+状态压缩 )

来源:互联网 发布:雨果博斯 知乎 编辑:程序博客网 时间:2024/06/05 15:23
这个题一开始想用六维数组直接跑的,但是考虑到药物或者序列更多的话就不实际了,这里我是用了hash对状态压缩然后DPhash: elfhash状态: 就是序列, 对应不同的结果保存最小解然后递归记忆求解#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define MAXV    10#define MAXC    11#define MAXN    1000001#define INF     0x7ffffffftypedef struct NODE_ {        int heat;        char mix_rst;}NODE;int  hash[MAXN], ans;NODE tab[MAXV][MAXV];char save[MAXN][MAXC], t[MAXC];inline int elf_hash(char *str){        unsigned long h( 0x0L ), x( 0x0L );        strcpy(t, str); char *ptr = t;        while( *ptr ) {                h = (h<<4)+(*ptr ++);                if( (x = h&0xF0000000L) ) {                        h ^= (x>>24); h &= ~x;                }        }        int idx( h%MAXN );        while( (INF != hash[idx]) && strcmp(str, save[idx]) ) {                idx = (idx+1)%MAXN;        }        strcpy(save[idx], str); return idx;}inline int mix_chemical(const char *str, const int &idx1, const int &idx2, char *des){        int x, y, s, f, idx(0), flag(0);        x = str[idx1]-'0'; y = str[idx2]-'0';        s = min(idx1, idx2); f = max(idx1, idx2);        des[idx ++] = tab[x][y].mix_rst;        for(int i = 0; i < strlen(str); i ++) {                if( i != idx1 && i != idx2 ) {                        des[idx ++] = str[i];                }        }        des[idx] = '\0'; return tab[x][y].heat;}int dfs(char *str){        if( 2 > strlen(str) ) {                return 0;        }        char tmp[MAXC];        int idx( elf_hash(str) ), rst(INF), x, y;        if( INF != hash[idx] ) {                return hash[idx];        }        for(int i = 0; i < strlen(str); i ++) {                for(int j = i+1; j < strlen(str); j ++) {                        rst = min(rst, mix_chemical(str, i, j, tmp)+dfs(tmp));                        rst = min(rst, mix_chemical(str, j, i, tmp)+dfs(tmp));                }        }        return hash[idx] = rst;}int main(int argc, char const *argv[]){#ifndef ONLINE_JUDGE        freopen("test.in", "r", stdin);#endif        int cas, n, m, v;        char str[MAXC], ch[3];        scanf("%d", &cas);        for( ; cas; cas --) {                scanf("%d", &n);                for(int i = 1; i <= n; i ++) {                        for(int j = 1; j <= n; j ++) {                                scanf("%d %d", &v, &tab[i][j].heat);                                 tab[i][j].mix_rst = v+'0';                        }                }                scanf("%d", &m);                for(int i = 0; i < m; i ++) {                        scanf("%d", &v); str[i] = v+'0';                }                str[m] = '\0'; scanf("%s", ch); ans = INF;                memset(save, '\0', sizeof(save));                for(int i = 0; i < MAXN; i ++) {                        hash[i] = INF;                }                printf("%d\n", dfs(str));        }        return 0;}