zoj 3034 - The Bridges of Kolsberg

题目:在河两端有两排服务器,现在要把河两边相同的品牌型号的机器连起来,每个电脑有个值,

           每个机器只能与另一台机器链接,并且不同的链接不交叉,现在要求链接的电脑总之最大。

分析:dp,最大公共子序列,字符串。还要加一个字符串处理。

说明:(2011-09-19 11:08)。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define max( a, b ) ((a)>(b)?(a):(b))

char LeftOS[ 1001 ][ 12 ];
char RightOS[ 1001 ][ 12 ];
int  LeftID[ 1001 ];
int  LeftV[ 1001 ];
int  RightID[ 1001 ];
int  RightV[ 1001 ];
char OSList[ 1001 ][ 12 ]; 
int  Match[ 1001 ][ 1001 ];
int  Count[ 1001 ][ 1001 ];
int  Number = 0;

int ID( char * Data ) 
{
    for ( int i = 0 ; i < Number ; ++ i )
        if ( !strcmp( OSList[ i ], Data ) )
            return i;
    strcpy( OSList[ Number ], Data );
    return Number ++;
}

int main()
{
    int  t,n,m;
    char City[ 12 ];
    while ( ~scanf("%d",&t) ) 
    while ( t -- ) {
        scanf("%d",&n);
        for ( int i = 1 ; i <= n ; ++ i )
            scanf("%s %s %d",City,LeftOS[ i ],&LeftV[ i ]);
        scanf("%d",&m);
        for ( int i = 1 ; i <= m ; ++ i )
            scanf("%s %s %d",City,RightOS[ i ],&RightV[ i ]);
        
        Number = 0;
        for ( int i = 1 ; i <= n ; ++ i )
            LeftID[ i ] = ID( LeftOS[ i ] );
        for ( int i = 1 ; i <= m ; ++ i )
            RightID[ i ] = ID( RightOS[ i ] );
        
        memset( Match, 0, sizeof( Match ) );
        memset( Count, 0, sizeof( Count ) );
        
        for ( int i = 1 ; i <= n ; ++ i )
        for ( int j = 1 ; j <= m ; ++ j ) {
            if ( Match[ i ][ j ] < Match[ i-1 ][ j ] ) {
                Match[ i ][ j ] = Match[ i-1 ][ j ];
                Count[ i ][ j ] = Count[ i-1 ][ j ];
            }
            if ( Match[ i ][ j ] < Match[ i ][ j-1 ] ) {
                Match[ i ][ j ] = Match[ i ][ j-1 ];
                Count[ i ][ j ] = Count[ i ][ j-1 ];
            }
            if ( LeftID[ i ] == RightID[ j ] && Match[ i ][ j ] < Match[ i-1 ][ j-1 ] + LeftV[ i ] + RightV[ j ] ) {
                Match[ i ][ j ] = Match[ i-1 ][ j-1 ] + LeftV[ i ] + RightV[ j ];
                Count[ i ][ j ] = Count[ i-1 ][ j-1 ] + 1;
            }
        }

        printf("%d %d\n",Match[ n ][ m ],Count[ n ][ m ]);
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值