题意:conversion的定义是下一句提到上一句的人的名字。请你输出最长的对话的长度,及组成对话的序列号。

思路:动态规划的思想很容易想到,当前句子,根据所有提到的人的名字为结尾组成的对话长度来判断当前name的最长对话长度。每个名字需要记录它形成最长对话的长度及此时出现的行数。

想说的是,C++处理起来好优雅。Cplusplusdeeplover.

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <vector>
#include <sstream>
#define maxn 50010
#include <map>
using namespace std;

int dp[maxn], pre[maxn];
string mess, word, name, str;

map<string, pair<int, int> >mp;

bool ok;

void print(int num) {
    if (num == -1) return;
    print(pre[num]);
    if (ok) {
        printf("%d", num+1);
        ok = false;
    }
    else printf(" %d", num+1);
    return;
}

int main() {
    //freopen("in.cpp", "r", stdin);
    int n;
    while(cin >> n) {
        getchar();
        mp.clear();
        for (int i=0; i<n; ++i) {
            getline(cin, str);
            //cout << str << "...\n";
            stringstream mess(str);
            mess >> name;
            name = name.substr(0, name.length()-1);
            dp[i] = 1;
            pre[i] = -1;
            while(mess>>word) {
                if (!mp.count(word) || word == name) continue;
                if (mp[word].first + 1 > dp[i]) {
                    dp[i] = mp[word].first + 1;
                    pre[i] = mp[word].second;
                }
            }
            if (!mp.count(name)) mp[name] = make_pair(dp[i], i);
            if (mp[name].first < dp[i]) mp[name].first = dp[i], mp[name].second = i;
        }

        int maxdp = -1, pos;
        ok = true;
        for (int i=0; i<n; ++i) {
            if (maxdp < dp[i]) {
                maxdp = dp[i];
                pos = i;
            }
        }
        cout << maxdp << endl;
        print(pos);
        cout << endl;
    }
    return 0;
}

 

posted on 2016-08-03 18:54  小小八  阅读(317)  评论(0编辑  收藏  举报