题目:有n个人站在一排,如果相邻的两人是‘8g’关系的话,他们就会跑掉(剩下的间隙忽略),求走掉的最大人数。
分析:dp,区间动态规划。
设 f(a,b )为区间[a,b]中的走掉的最大值,可分为以下情况:
1.两端匹配(d[a] == d[b])
如果 f(a+1,b-1) == b-a-1则 f(a,b)= f(a+1,b-1)+2;否则,按位情况2处理;
2.两端不匹配(d[a] != d[b])
f(a,b)= max(f(a,c),f(c+1,b))
说明:大黄的 floyd+统计的 比我快了 3倍。。。 (2011-9-25 00:53)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
bool maps[ 301 ][ 301 ];
int data[ 301 ];
int F[ 301 ][ 301 ];
int main()
{
int n,m,a,b;
while ( scanf("%d%d",&n,&m) != EOF ) {
memset( maps, false, sizeof( maps ) );
for ( int i = 1 ; i <= m ; ++ i ) {
scanf("%d%d",&a,&b);
maps[ a ][ b ] = true;
maps[ b ][ a ] = true;
}
for ( int i = 1 ; i <= n ; ++ i )
scanf("%d",&data[ i ]);
memset( F, 0, sizeof( F ) );
for ( int i = 1 ; i < n ; ++ i )
if ( maps[ data[ i ] ][ data[ i+1 ] ] )
F[ i ][ i+1 ] = 2;
for ( int i = n-2 ; i >= 1 ; -- i )
for ( int j = i+2 ; j <= n ; ++ j )
if ( F[ i+1 ][ j-1 ] == j-i-1 && maps[ data[ i ] ][ data[ j ] ] )
F[ i ][ j ] = j-i+1;
else {
for ( int k = i ; k < j ; ++ k )
if ( F[ i ][ j ] < F[ i ][ k ] + F[ k+1 ][ j ] )
F[ i ][ j ] = F[ i ][ k ] + F[ k+1 ][ j ];
}
printf("%d\n",F[ 1 ][ n ]);
}
return 0;
}