UVA10066 The Twin Towers【LCS+DP+记忆化递归】

Once upon a time, in an ancient Empire, there were two towers of dissimilar shapes in two different cities. The towers were built by putting circular tiles one upon another. Each of the tiles was of the same height and had integral radius. It is no wonder that though the two towers were of dissimilar shape, they had many tiles in common.
    However, more than thousand years after they were built, the Emperor ordered his architects to remove some of the tiles from the two towers so that they have exactly the same shape and size, and at the same time remain as high as possible. The order of the tiles in the new towers must remain the same as they were in the original towers. The Emperor thought that, in this way the two towers might be able to stand as the symbol of harmony and equality between the two cities. He decided to name them the Twin Towers.
    Now, about two thousand years later, you are challenged with an even simpler problem: given the descriptions of two dissimilar towers you are asked only to find out the number of tiles in the highest twin towers that can be built from them.
Input
The input file consists of several data blocks. Each data block describes a pair of towers. The first line of a data block contains two integers N1 and N2 (1 ≤ N1, N2 ≤ 100) indicating the number of tiles respectively in the two towers. The next line contains N1 positive integers giving the radii of the tiles (from top to bottom) in the first tower. Then follows another line containing N2 integers giving the radii of the tiles (from top to bottom) in the second tower.
    The input file terminates with two zeros for N1 and N2.
Output
For each pair of towers in the input first output the twin tower number followed by the number of tiles (in one tower) in the highest possible twin towers that can be built from them. Print a blank line after the output of each data set.
Sample Input
7 6
20 15 10 15 25 20 15
15 25 10 20 15 20
8 9
10 20 20 10 20 10 20 10
20 10 20 10 10 20 10 10 20
0 0
Sample Output
Twin Towers #1
Number of Tiles : 4

Twin Towers #2
Number of Tiles : 6

问题链接UVA10066 The Twin Towers
问题简述:由不同的石头组成的两座塔,去掉一些石头让两个塔一样,求塔剩下的最大高度。
问题分析
    最长公共子序列问题,一个模板题,只是2组数据长度不一样。
    给出2种解法。
程序说明:(略)
参考链接UVA111 History Grading【LCS+DP+记忆化递归】
题记:(略)

AC的C++语言程序(记忆化递归)如下:

/* UVA10066 The Twin Towers */

#include <bits/stdc++.h>

using namespace std;

const int N = 100 + 1;
int a[N], b[N], dp[N][N];

int lcs(int r, int c)
{
    if(dp[r][c] != -1) return dp[r][c];
    else if(r == 0 || c == 0) return dp[r][c] = 0;
    else if(a[r] == b[c]) return dp[r][c] = lcs(r - 1, c - 1) + 1;
    else return dp[r][c] = max(lcs(r, c - 1), lcs(r - 1, c));
}

int main()
{
    int n1, n2, caseno = 0;
    while(~scanf("%d%d", &n1, &n2) && (n1 || n2)) {
        for(int i = 1; i <= n1; i++) scanf("%d", &a[i]);
        for(int i = 1; i <= n2; i++) scanf("%d", &b[i]);

        memset(dp, -1, sizeof(dp));

        printf("Twin Towers #%d\n", ++caseno);
        printf("Number of Tiles : %d\n", lcs(n1, n2));
        printf("\n");
    }

    return 0;
}

AC的C++语言程序如下:

/* UVA10066 The Twin Towers */

#include <bits/stdc++.h>

using namespace std;

const int N = 100 + 1;
int a[N], b[N], dp[N][N];

int main()
{
    int n1, n2, caseno = 0;
    while(~scanf("%d%d", &n1, &n2) && (n1 || n2)) {
        for(int i = 1; i <= n1; i++) scanf("%d", &a[i]);
        for(int i = 1; i <= n2; i++) scanf("%d", &b[i]);

        memset(dp, 0, sizeof(dp));
        for(int i = 1; i <= n1; i++)
            for(int j = 1; j <= n2; j++)
                if(a[i] == b[j]) dp[i][j] = dp[i - 1][j - 1] + 1;
                else dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]);

        printf("Twin Towers #%d\n", ++caseno);
        printf("Number of Tiles : %d\n", dp[n1][n2]);
        printf("\n");
    }

    return 0;
}
原创文章 2323 获赞 2382 访问量 269万+

猜你喜欢

转载自blog.csdn.net/tigerisland45/article/details/105801269