题意: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; }