WordStack

https://ac.nowcoder.com/acm/problem/107414

这个题一定要好好读题,尤其是对于与上一个字符串对比的得分是怎么计算的,不是连续子串相同,不是最大公共子序列,而是对齐情况下,最大相同的字符个数。题目中的示例正好避开了这个说明,导致思路错误。

链接:https://ac.nowcoder.com/acm/problem/107414
来源:牛客网

padding them with leading spaces to maximize the number of non-space characters that are the same as the character immediately above them on the preceding line.

好好注意上面的一句话,是说,可以增加空格,使上下的字符串对齐,得分是上下相同的字符个数,上面加粗的是单数,不是复数,并且牛客上面这个题的注释是错误的,也使我们产生了误解。这道题原题来自北京大学ACM题库,如下

http://poj.org/problem?id=2817

北京大学网站上的示例是这样的

而牛客上是这样的

很明显cde的一行少移了一位,导致我们对题目理解出错。

https://www.nowcoder.com/ta/acm-solutions/review?tpId=20&tqId=11228&query=2817&asc=true&order=&page=1

上面是唯一一个题解,在字符串是10的时候,结果是错误的,这个题解在北大的网站上也是通过的,但是题目中明确说明了每个单词长度从1-10,包含10(如果我没理解错的话),如下:

链接:https://ac.nowcoder.com/acm/problem/107414
来源:牛客网

Each word will be made up of the characters 'a' to 'z' and will be between 1 and 10 characters long (inclusive).

也就是牛客和北大网站上的case都没覆盖边界情况。

理解了这道题,那么思路就是,首先创建一个表,用来保存每两个单词之间相同的字符个数,也就是得分数,然后呢,就是找到一个排序,让每个单词与上一个之间得分总数最大。

这道题整体的思路就是dp,创建单词间的得分可以dp,计算单词如何排序而达到最大值也可以dp。这里计算得分的时候使用的dp,因为分配的空间少一些,计算排序的话,用的穷举法,因为就是排列,最多10个的话,总的计算量不算大,如果用dp,思路有点绕,没有想通这种方法,代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<set>
#include<climits>
using namespace std;
char INPUT_STR[11][11] = { 0 };
int DP[11][11] = { 0 };
int MAX_SCORE = 0;
int MAX_SOCRE_STR_SORT[10] = { 0 };
int INPUT_NUM = 0;

void swap(int &a, int &b)
{
    int temp = a;
    a = b;
    b = temp;
}

void perm(int arrindex[], int low, int high)
{
    if (low == high)
    {
        int tmpmaxn = 0;
        for (int i = 1; i < INPUT_NUM; i++)
        {
            tmpmaxn += DP[arrindex[i]][arrindex[i - 1]];
        }
        if (tmpmaxn > MAX_SCORE)
        {
            MAX_SCORE = tmpmaxn;
            for (int i = 0; i < INPUT_NUM; i++)
            {
                MAX_SOCRE_STR_SORT[i] = arrindex[i];
            }
        }
    }
    else
    {
        for (int i = low; i <= high; i++)
        {
            swap(arrindex[i], arrindex[low]);
            perm(arrindex, low + 1, high);
            swap(arrindex[i], arrindex[low]);
        }
    }
}
int get_max_lcs(char *stra, char *strb)
{
    int LCS_DP[10][10] = { 0 };
    int slena = strlen(stra);
    int slenb = strlen(strb);
    int maxnum = 0;
    for (int i = 0; i < slena; i++)
    {
        for (int j = 0; j < slenb; j++)
        {
            int pren = 0;
            if (i > 0 && j > 0)
            {
                pren = LCS_DP[i - 1][j - 1];
            }
            if (stra[i] == strb[j])
            {
                LCS_DP[i][j] = pren + 1;
            }
            else
            {
                LCS_DP[i][j] = pren;
            }
            if (LCS_DP[i][j] > maxnum)
            {
                maxnum = LCS_DP[i][j];
            }
        }
    }
    return maxnum;
}
int main()
{
    while (cin >> INPUT_NUM && INPUT_NUM > 0)
    {
        MAX_SCORE = 0;
        memset(MAX_SOCRE_STR_SORT, 0, 10 * sizeof(int));
        memset(DP, 0, 10 * sizeof(int));
        memset(INPUT_STR, 0, 10 * sizeof(char));
        int* arrindex = new int[INPUT_NUM];
        for (int i = 0; i < INPUT_NUM; i++)
        {
            cin >> INPUT_STR[i];
            *(arrindex + i) = i;
        }
        for (int i = 0; i < INPUT_NUM; i++)
        {
            for (int j = i + 1; j < INPUT_NUM; j++)
            {
                DP[i][j] = get_max_lcs(INPUT_STR[i], INPUT_STR[j]);
                DP[j][i] = DP[i][j];
            }
        }
        perm(arrindex, 0, INPUT_NUM - 1);
        delete[] arrindex;
        cout << MAX_SCORE << endl;
    }
}

posted @ 2020-09-08 13:08  秋来叶黄  阅读(175)  评论(0编辑  收藏  举报