zoj3160Couples

来源:互联网 发布:python .shift[1] 编辑:程序博客网 时间:2024/06/05 15:23

zoj3160Couples

In the world ofknowledge, so many new words appear on the internet. A special one is"8g", a kind of special relationship between two persons. (If youwant to know more words, just turn to a search engine.)

You aregiven n people and the "8g"relationships between them. Now they are standing in one line and the followingthings may happen.
1. If two persons with "8g" relationship stands next to each other,they may run away and never come back.
2. If the people between the ith person andthe jth person all ran away, now the ithone and the jth one areconsidered to be next to each other.

According to therules, when a person has "8g" relationships with the two persons inhis/her two sides. He/She can run with either one. So there may be many ways inwhich people could run.

So, for allpossibility, we want to know the maximum number of persons that can run intotal.

Input

The first line ofeach case will contain two integers n(2 <= n <=300) and m, indicating the number of persons and thenumber of "8g" relationships(Persons are indexed from 0 to n - 1).Next m lines contains two integers a and b, meaning thatthere is a "8g" relationship between a and b. Then followed bya line containing a permutation of 0 to n - 1, meaning the arrangement of the npersons. Proccess to the end of file.

Output

For each case,print one line containing the maximum number of people that can run in total.

Sample Input

4 2

0 3

1 2

0 1 2 3

Sample Output

4



         【分析】n个人,其中有若干个人有关系,若有关系的两人站在一起(相邻),他们就会离开,他们旁边的两人就变成了相邻的了,求可以走掉的最大人数。

         区间DP

#include<iostream>

#include<cstdio>

#include<cstring>

using namespace std;

int vis[ 301 ][ 301];

int data[ 301 ];

int dp[ 301 ][ 301 ];

 

int main()

{

    int n,m,a,b;

    while (scanf("%d%d",&n,&m) != EOF ) {

        memset( vis,0,sizeof( vis ) );

        for ( int i = 1 ; i <= m ; ++ i ) {

           scanf("%d%d",&a,&b);

            vis[a][b] = 1;

            vis[b][a] = 1;

        }

        for (int i=1;i<=n;++i)

            scanf("%d",&data[i]);

 

        memset(dp,0,sizeof(dp));

        for (int i=1;i<n;++i )

            if (vis[data[i]][data[i+1]])

                dp[i][i+1] = 2;

 

        for (int i = n-2;i >= 1;i--)

        for (int j = i+2;j <= n;j++)

            if (dp[i+1][j-1] == j-i-1&& vis[data[i]][data[j]])

                dp[i][j] = j-i+1;

            else {

                for ( int k = i ; k < j ; ++k )

                    if ( dp[i][j] < dp[i][k]+ dp[k+1][j] )

                        dp[i][j] = dp[i][k] +dp[k+1][j];

            }

 

        printf("%d\n",dp[1][n]);

    }

    return 0;

}

 

0 0
原创粉丝点击