dp(UVa 10604 - Chemical Reaction)

Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu

Submit Status

Description

Download as PDF

 

In a chemist’s lab, there are several types of chemicals in tubes. The chemist wants to mix all these chemicals together, two chemicals at a time. Whenever two chemicals are mixed, some heat is generated and released into the air and the mixed chemical is a known chemical of possibly other type than the original two. The resulting chemical type and the amount of heats emitted can looked up in the chemical mixture table.

 

Chemicals

1

2

3

Resulting chemical type

Heats emmited

Resulting chemical type

Heats emmited

Resulting chemical type

Heats emmited

1

1

0

3

-10

3

3000

2

3

-10

2

0

1

-500

3

3

3000

1

-500

3

0

 

For example, in the above chemical mixture table, there are three types of chemicals: 1, 2, and 3. If you mix chemicals 1 and 3, they produce +3000 units of heat and turn into chemical 3. Sometimes, the heat generated can be negative. For instance, you can mix 2 and 3 and they turn into chemical 1 and in the meantime, cool down the lab by 500 units of heat. Since the chemist lacks funding to buy necessary equipments to protect himself from the heat generated, it is utmost important to find a way to mix all the chemicals together that produces the least total heat, regardless of the final chemical type. For example, suppose the lab has four tubes containing chemicals of types 1, 2, 2, and 3. If the chemicals are mixed in the parenthesize order of ((1 2) (2 3)), it will produce (–10)+ (-500)+(3000) = 2490 units of heat. However, if the chemicals are mixed in the (2 (1 (2 3))) order, it will produce (-500)+0+(-10)= -510 units of heat, which is also the least total heat possible.

 

Input

The first line of input file consists of a single number denoting the number of test cases in the file. There is a single line containing a ‘/’ character separating two consecutive test cases. The end of the file is marked with a line containing a ‘.’ For each test case, the first line contains an integer number m (1≤m≤6) denoting the number chemical types. Therefore, the chemicals are indexed from 1 up to at most 6. The next mxm lines give the chemical mixture table entries in the row-major order. Each line contains the new resulting chemical type and the amount of energy emitted. After the table entries is a line with a single number k (2≤k≤10) denoting number of tubes in the lab. The next line then contains k integers in the range of 1 and m, separated by blank spaces, denoting the types of chemicals in those k tubes.

 

Output

For each test case, output the least total heat possible on a single line.

 

Sample Input

Sample Output

2

3

1 0

3 -10

3 3000

3 -10

2 0

1 -500

3 3000

1 -500

3 0

4

1 2 2 3

/

3

1 0

3 500

3 -250

3 500

2 0

1 100

3 -250

1 100

3 0

6

1 1 1 2 2 3

.

-510

-650

思路:hash+记忆话搜索

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=20;
const int INF=1000000000;
struct node
{
    int res,heat;
}a[maxn][maxn];
int N,M,cnt[maxn];
int dp[1000010];

int gethash()
{
    int sum=0;
    int dig=1;
    for(int i=1;i<=6;i++)
    {
        sum+=cnt[i]*dig;
        dig*=10;
        //sum=sum*10+cnt[i];
    }
    return sum;
}
int DP(int S)
{
    if(dp[S]!=-1)return dp[S];
    dp[S]=INF;
    for(int i=1;i<=6;i++)
    {
        for(int j=1;j<=6;j++)
        {
            if((i==j&&cnt[i]>=2)||(i!=j&&cnt[i]>=1&&cnt[j]>=1))
            {
                cnt[i]--,cnt[j]--;
                cnt[a[i][j].res]++;
                dp[S]=min(dp[S],a[i][j].heat+DP(gethash()));
                cnt[i]++,cnt[j]++;
                cnt[a[i][j].res]--;
            }
        }
    }
    return dp[S]=dp[S]==INF?0:dp[S];
}

int main()
{
    int T;
    char op[5];
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&N);
        for(int i=1;i<=N;i++)
            for(int j=1;j<=N;j++)scanf("%d%d",&a[i][j].res,&a[i][j].heat);
        scanf("%d",&M);
        memset(cnt,0,sizeof(cnt));
        for(int i=1;i<=M;i++)
        {
            int x;
            scanf("%d",&x);
            cnt[x]++;
        }
        memset(dp,-1,sizeof(dp));
        printf("%d\n",DP(gethash()));
        scanf("%s",op);
        if(op[0]=='.')break;
    }
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值