2013-08-28 07:41:59Morris

[UVA][dp] 1172 - The Bridges of Kolsberg

Problem F - The Bridges of Kölsberg

Background

King Beer has a very hard region to rule, consisting of lots of cities with very sectarian operating system beliefs and high levels of trade. These cities are placed along a river, the Kölsberg, along its Northern and Southern banks. The cities are economically separated from each other, since the river is wide and dangerous.




A section of the Kölsberg showing some invalid bridges

King Beer would like to build some bridges connecting opposite banks of the river.  He was strongly advised against making bridges between cities with different operating systems beliefs (those guys really hate each other). So, he is just going to build bridges between cities sharing the same operating system belief (even if the resulting bridges are quite long and strangely shaped). However, it is technical impossible to build bridges that cross other bridges.

The economical value of a bridge is the sum of the trade values the two cities it connects. The King wants to maximize the sum of all possible bridge values while minimizing the number of bridges to build.

Problem

Given two sets of cities, return the maximum possible sum of all bridge values and the smallest number of valid bridges necessary to achieve it.

Input

The first line is an integer with the number of samples. For each sample, the next line has a non-negative integer, not greater than 1,000, indicating the number of cities on the Northern riverbank. Then, on each line, comes the city information with the form

 

cityname ostype tradevalue

 

where, separated by empty spaces, there are two strings, cityname and ostype, with no more than 10 characters each, and tradevalue which is a non-negative integer not greater than 106. The sequence of lines represents the cities from left to right along the riverbank. Next, there is the same kind of information to describe the Southern riverbank.

Output

For each sample, a line consisting of the maximum possible sum of all bridge values, one empty space, the number of bridges.

Sample Input

1
3

mordor Vista 1000000

xanadu Mac 1000

shangrila OS2 400

4

atlantis Mac 5000

hell Vista 1200

rivendell OS2 100

appleTree Mac 50

Sample Output

1002250 2

 



題目描述:


兩個序列建橋,橋不可相交,求所有橋的兩端貿易值最大總和。
並且橋越少越好。

題目解法:


類似於 LCS,dp[i][j] 表示當前第一序列到 i, 第二序列到 j

不管 i, j 有沒有在橋的另一端, dp[i][j] = max(dp[i-1][j], dp[i][j-1])

假使 i, j 可以建一座橋 dp[i][j] = max(dp[i-1][j-1] + value[i] + value[j]);

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
char Aostype[1005][20], Bostype[1005][20];
int A[1005], B[1005];
int dp1[1005][1005], dp2[1005][1005];
int main() {
    int testcase, n, m, i, j, k;
    scanf("%d", &testcase);
    while(testcase--) {
        scanf("%d", &n);
        for(i = 1; i <= n; i++)
            scanf("%*s %s %d", &Aostype[i], &A[i]);
        scanf("%d", &m);
        for(i = 1; i <= m; i++)
            scanf("%*s %s %d", &Bostype[i], &B[i]);
        memset(dp1, 0, sizeof(dp1));
        memset(dp2, 0, sizeof(dp2));
        for(i = 1; i <= n; i++) {
            for(j = 1; j <= m; j++) {
                dp1[i][j] = dp1[i-1][j];
                dp2[i][j] = dp2[i-1][j];
                if(dp1[i][j-1] > dp1[i][j] ||
                   (dp1[i][j-1] == dp1[i][j] && dp2[i][j-1] < dp1[i][j])) {
                    dp1[i][j] = dp1[i][j-1];
                    dp2[i][j] = dp2[i][j-1];
                }
                if(!strcmp(Aostype[i], Bostype[j])) {
                    int val1 = dp1[i-1][j-1] + A[i] + B[j];
                    int val2 = dp2[i-1][j-1] + 1;
                    if(val1 > dp1[i][j] || (val1 == dp1[i][j] && val2 < dp2[i][j]))
                        dp1[i][j] = val1, dp2[i][j] = val2;
                }
            }
        }
        printf("%d %d\n", dp1[n][m], dp2[n][m]);
    }
    return 0;
}
xem phim online 2017-10-03 14:12:42

nice article...