大体题意:
给你n 行对话,刚开始告诉你人的姓名,其次是对话内容,要求求一个最长的长度,使得下一个对话的内容包括上一个对话的人的姓名?
思路:
赛后补得题目:
Dp思想!
令dp[i]表示枚举到第i 行 所能得到的最大值!
===========================================
记录一下整个思考的过程吧,因此错了很多遍!
首先想到的是利用map<string,Node> 来记录,第一个string 记录对话人的姓名,第二个结构体里存放一些东西!
struct Node{
int d,pos,last;
}
其中d 就表示dp记录的东西,走到这个人得到的最大值,pos 是记录到这个人最大的位置,last 表示前面的路径!
然后转移就很好转移了,在枚举第i 行时,先确保这个人的map 一定存在,初始化他的Node,然后在枚举这个人的内容,如果发现在map中存在了,就把存在的那个人的信息(d)转移到当前这个人,然后在记录路径!
这样整个过程就相当于用map 来记录dp了,打印路径还得需要5w的string 数组进行初始化!
以上整个思路 是超时的!
==============================================
针对以上情况,很明显超时超在 5w个string 数组的初始化上,那么优化肯定就不能再用他了,所以直接在开两个数组单独记录dp 和路径pre
这样也有个好处 不用每次都memset,因为只需要在枚举新的一行时 初始化当前的dp 和pre 即可!
这样省了好多时间,也去掉了Node 中的last变量!
那么最后统计答案 只需要统计 1~n 的最大dp 即可! 然后记录最大值的位置,pre回去即可!
详细见代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <string>
#include <sstream>
#include <stack>
#include <iostream>
using namespace std;
const int maxn = 50000 + 10;
struct Node{
int d, pos;
};
int dp[maxn],pre[maxn];
map<string,Node>mp;
stack<int>sk;
int cur = 0;
int main(){
int n;
string s,name,t;
while(scanf("%d%*c",&n) == 1){
mp.clear();
for (int i = 1; i <= n; ++i){
getline(cin,s);
stringstream ss(s);
ss >> name;
name.resize(name.length() - 1);
// names[i] = name;
// cout << name <<endl;
if (!mp.count(name)){
Node u;
u.d = 1;
u.pos = i;
// u.last = -1;
mp[name] = u;
}
pre[i] = -1;
dp[i] = 1;
while(ss >> t){
if (!mp.count(t) || t == name)continue;
if (dp[i] < mp[t].d + 1){
dp[i] = mp[t].d + 1;
pre[i] = mp[t].pos;
}
}
if (mp[name].d < dp[i]){
mp[name].d = dp[i];
mp[name].pos = i;
}
}
int ans = 0,p = 1;
for (int i = 1; i <= n; ++i){
if (ans < dp[i]){
p = i;
ans = dp[i];
}
}
printf("%d\n",ans);
while(p != -1){
sk.push(p);
p = pre[p];
}
int cnt = 0;
while(!sk.empty()){
if (cnt++)printf(" ");
printf("%d",sk.top());
sk.pop();
}
puts("");
}
return 0;
}
/**
5
@Petr: Leaving for #NEERC tomorrow!
@Roman: This #NEERC is going to be awesome!
@Stone in forest: Nothing happened today.
@NEERCNews: @Petr Don’t forget an umbrella :)
@Lydia: @NEERCNews cares about @Petr - so cute ^ ^
6
@Petr: Leaving for #NEERC tomorrow!
@Roman: This #NEERC is going to be awesome!
@Stone in forest: Nothing happened today.
@NEERCNews: @Petr Don’t forget an umbrella :)
@Lydia: @NEERCNews cares about @Petr - so cute ^ ^
@Lydia: @Lydia @NEERCNews @Petr it won’t be raining though!
**/