首页 > 代码库 > POJ 1770 Special Experiment

POJ 1770 Special Experiment

Special Experiment
Time Limit: 1000MS Memory Limit: 30000K
Total Submissions: 1790 Accepted: 601

Description

As we know, an atom can be in different energy states (or "energy levels"). Usually, when it transits from a higher energy state to a lower one, it will emit a photon, whose energy is equal to the difference in energy of these two states. Absorption of photons is the reverse process. If a photon, whose energy equal to the difference in energy of two states of an atom, passes by, it may be absorbed and its energy will put the atom into a higher energy level. For most elements, the atom can transit between any two states directly, by emitting or absorbing only one photon.Scientists are puzzled by a new element that they discovered recently. For two certain energy states, the atom of this element can transit between them directly (emitting or absorbing one and only one photon), but for some other pairs of energy states, the atom cannot. 
Generally speaking, when an atom transits among energy states one after another, a trail of events (emitting or absorbing a photon) occurs. For example, when transiting from energy state 
Ei1 to Eit, the atom follows this sequence: 
Ei1, Ei2, Ei3, ..., Eik, ..., Eit

Eik (1 <= k <= t) represents a certain energy state. During the of process of transiting from Eik to Eik+1 , one and only one photon is emitted or absorbed. 
The atom can be in any energy state and transit to some other one. But as we mentioned above, for some pairs of energy states, this special atom cannot transit between them directly. What‘s more,when its energy state changes from one to another, for example, from Ej1 to Ejw , it can only follow a unique sequence Ej1 ,Ej2 ,Ej3 ,... , Ejw . And the most interesting thing is that it can only follow another unique sequence Ejw, ...,Ej3 ,Ej2 ,Ej1 , when it transits back from Ejw to Ej1 .You can find that it is the reversion of the former one! Right! Isn‘t it special? 
Now, the scientists need your help today. In an experiment, some atoms of this new element will be put into a container. Any two atoms would be regarded as "dangerous atoms" if they satisfy one of the following conditions: 
  • They are in the same energy state. 
  • They are in different energy states. But if one of them emits or absorbs a photon, they will be in the same states too.

You must make sure that there are no dangerous atoms in this container. And the higher the total energy of the atoms in the container is, the more easily will the experiment succeed. 
Now, the scientists have told you all photons that the atoms of this element can emit or absorb, as well as the energy of all atom states. They ask you calculate the highest total energy that the atoms in the container can reach.

Input

There are several testcases in the input. Each begins with a line containing two integers N, M (0 < N, M <= 200), representing the number of the energy levels and the number of the different photons that this kind of atom can emit or absorb respectively. The two numbers are followed by exactly N + M lines, which contain one positive integer each. These N+M positive integers are not greater than 1,000,000. The first N distinguishing integers are the energy of the atom in the N different energy states in ascending order. The next M integers correspond to the energy of the M different photons, which can be emitted or absorbed by atoms of this element. If the difference in energy of any two states equals to the energy of one of the M photons, the atom can transit between these two states directly. 
There is no blank line between two data sets. The last testcase is followed by a line containing two zeros.

Output

For each testcase, output one line containing an integer, which indicates the highest total energy that the atoms in the container can reach. There should be no blank line between any two cases.

Sample Input

3 1
2
4
6
2
0 0

Sample Output

8

Source

Asia Guangzhou 2003

树形DP啊, 没有读清题意,考虑到有环的情况,其实题意说的是无环
互斥的两个点连边没有环构成树,然后树形DP
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdio>
#define N 210
#define M 1000010
using namespace std;
int a[N],dp[N][2];
bool status[M],ch[N];
int n;
int main()
{
    //freopen("data.txt","r",stdin);
    int dfs(int k);
    int m;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        if(!n&&!m)
        {
            break;
        }
        int Top = 1;
        memset(status,false,sizeof(status));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[Top]);
            if(!status[a[Top]])
            {
                status[a[Top]] = true;
                Top++;
            }
        }
        Top-=1;
        n = Top;
        sort(a+1,a+n+1);
        memset(status,false,sizeof(status));
        for(int i=1;i<=m;i++)
        {
            int x;
            scanf("%d",&x);
            status[x] = true;
        }
        memset(ch,false,sizeof(ch));
        memset(dp,0,sizeof(dp));
        int res = 0;
        for(int i=1;i<=n;i++)
        {
            if(!ch[i])
            {
                res+=dfs(i);
            }
        }
        printf("%d\n",res);
    }
    return 0;
}
int dfs(int k)
{
    bool uv = true;
    ch[k] = true;
    for(int i=1;i<=n;i++)
    {
        if(k==i)
        {
            continue;
        }
        if(status[abs(a[i]-a[k])]&&!ch[i])
        {
            uv = false;
            break;
        }
    }
    if(uv)
    {
        dp[k][0] = 0;
        dp[k][1] = a[k];
        return max(dp[k][0],dp[k][1]);
    }
    for(int i=1;i<=n;i++)
    {
        if(k==i)
        {
            continue;
        }
        if(status[abs(a[i]-a[k])]&&!ch[i])
        {
            dfs(i);
            dp[k][0]+=max(dp[i][0],dp[i][1]);
            dp[k][1]+=dp[i][0];
        }
    }
    dp[k][1]+=a[k];
    return max(dp[k][0],dp[k][1]);
}