CodeForces - 191A Dynasty Puzzles(dp)

以你之姓@ 2022-06-07 03:15 186阅读 0赞

点我看题

题意:就是有一些字符串作为名字,每个串前面的最后一个字母和当前串的前一个字母相同则可以连接起来,最终要求首尾字母相同的串的最大长度为多少.

分析:(eeeeem,作为dp方面的辣鸡,还是很不齿的写下了这边博客即使这题很简单

比赛的时候是记录每个串是否能够和前面某一个串进行拼接,显而易见这种想法完全不可取,然后,看了题解,额这个题确实比较简单,首先我们用dp[i][j]表示字符串以i(i+’a’)开始,以j(j+’a’)结束的串的最大长度,那么dp[i][j]的转移方程应该怎么写呢?我们先依次遍历每一个串,串的首字母为p,尾字母为q,依次遍历26个字母,先判断dp[j][p]是否存在,存在的话,那么专用方程dp[j][q]=max(dp[j][q],dp[j][p]+len);其中len为当前字符串的长度,最后做一个更新dp[p][q]=max(dp[p][q],len),处理完这些就要去找一个最终答案了,最终答案要满足首尾字母相同,所以也就是dp[i][i]里面最大的那个.

参考代码:

  1. #include<cstdio>
  2. #include<cmath>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<iostream>
  6. using namespace std;
  7. #define mem(a,b) memset(a,b,sizeof(a))
  8. const int maxn = 5e5+10;
  9. int n;
  10. char name[maxn][15];
  11. int dp[30][30];
  12. int main()
  13. {
  14. while( ~scanf("%d",&n))
  15. {
  16. mem(dp,0);
  17. for( int i = 0; i < n; i++)
  18. scanf("%s",name[i]);
  19. for( int i = 0; i < n; i++)
  20. {
  21. int len = strlen(name[i]);
  22. int p = name[i][0]-'a';
  23. int q = name[i][len-1]-'a';
  24. for( int j = 0; j < 26; j++)
  25. {
  26. if( !dp[j][p])
  27. continue;
  28. dp[j][q] = max(dp[j][q],dp[j][p]+len);
  29. }
  30. dp[p][q]=max(dp[p][q],len);
  31. }
  32. int ans = 0;
  33. for( int i = 0; i < 26; i++)
  34. ans = max(ans,dp[i][i]);
  35. printf("%d\n",ans);
  36. }
  37. return 0;
  38. }

发表评论

表情:
评论列表 (有 0 条评论,186人围观)

还没有评论,来说两句吧...

相关阅读

    相关 CodeForces679A

    [CodeForces679A][] 也是交互题,这个要稍微难一些. 考虑的过程大概是: \\(1\\)肯定没有问的价值,如果问过\\(2\\),那么除了\\(4\

    相关 CodeForces1214A

    [CodeForces1214A][] 说起来你们可能不信,这题硬生生卡了我\\(1h\\),我想了背包,扩欧,二分....等等一坨办法.结果最后还是用了\\(bfs\\)

    相关 codeforce 141A

    /字符串问题 没AC的人可能是没看清楚题目吧, 先大概说下题目大意: 给你3个字符串,如果第一个串和第二个串组合在一起可以等于第三个串就输出“Y