UVa 10618 Fun Game

题目:

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=36035

思路:

  一圈人围坐,给出小球的传递序列,求解最少有多少个人。

问题简单化:如果有一排人,单向传递,给出序列求解最少多少人。那么问题就是:求解一个最短序列使得给出的所有序列都是该序列的连续子序列。

再分别解决以下问题:

  1. 第一个人可以向左向右传递: 每个传递序列有两种情况,分别是正序与逆序。因为不清楚当前序列是向左传还是向右传。
  2. 传递是一个环:规定将第一个序列正向串作为首序列,累计答案的时候只需要算上重叠部分即可。
  3. 输入可能是绕过好几圈的情况:如果绕过好几圈,那么其他的字串因已经被包含而舍弃,dp过程不会进行,最后累计ans时ans=len[0]-重叠(s[0][0],s[0][0])即最小循环节的长度。
  4. 输入保证n>=2:当ans<=1是修改为2

代码:

 

  1. #include<iostream>
  2. #include<cstring>
  3. #include<vector>
  4. #include<algorithm>
  5. #define FOR(a,b,c) for(int a=(b);a<(c);a++)
  6. using namespace std;
  7.  
  8. const int maxn = ;
  9. const int maxlen= + ;
  10.  
  11. struct Node{
  12. string s,rev;
  13. bool operator <(const Node& rhs) const{
  14. return s.size()<rhs.s.size(); //size由小到大
  15. }
  16. };
  17.  
  18. int n;
  19. int d[<<maxn][maxn][];
  20. int overlap[maxn][maxn][][];
  21. string s[maxn][];
  22. int len[maxn];
  23.  
  24. //return a右 && b左的重叠部分
  25. int make_overlap(const string& a,const string& b){
  26. int n1=a.size();
  27. int n2=b.size();
  28. FOR(i,,n1) { //找到最小重合点 即返回最大重合长度
  29. if(n2 + i <= n1) continue;
  30. bool ok=true;
  31. for(int j=;i+j<n1;j++)
  32. if(a[i+j] != b[j]) { ok=false; break; }
  33. if(ok) return n1-i;
  34. }
  35. return ; //无重合
  36. }
  37.  
  38. void init() {
  39. Node nodes[maxn];
  40. FOR(i,,n) {
  41. cin>>nodes[i].s;
  42. nodes[i].rev=nodes[i].s;
  43. reverse(nodes[i].rev.begin(),nodes[i].rev.end()); //反转串
  44. }
  45.  
  46. sort(nodes,nodes+n); //sort
  47. int nn=;
  48. FOR(i,,n) {
  49. bool need=true;
  50. FOR(j,i+,n)
  51. if(nodes[j].s.find(nodes[i].s) != string::npos ||
  52. nodes[j].rev.find(nodes[i].s) != string::npos){ //如果被包含则舍弃
  53. need=false; break;
  54. }
  55. if(need) {
  56. s[nn][]=nodes[i].s;
  57. s[nn][]=nodes[i].rev;
  58. len[nn]=s[nn][].size();
  59. nn++;
  60. }
  61. }
  62. n=nn;
  63.  
  64. //构造重叠数组
  65. FOR(i,,n) FOR(x,,)
  66. FOR(j,,n) FOR(y,,)
  67. overlap[i][j][x][y]=make_overlap(s[i][x],s[j][y]);
  68. }
  69.  
  70. inline void update(int& x,int v) {
  71. if(x< || v<x) x=v;
  72. }
  73.  
  74. void solve() {
  75. memset(d,-,sizeof(d));
  76. d[][][]=len[]; //始终把s[0][0]放在首位
  77.  
  78. int full=<<n;
  79. FOR(s,,full)
  80. FOR(i,,n) FOR(x,,) if(d[s][i][x]>=) //已求过集合中的枚举
  81. FOR(j,,n) if(!((<<j) & s)) FOR(y,,) //刷表更新的目标枚举
  82. update(d[s|(<<j)][j][y], d[s][i][x] + len[j]-overlap[i][j][x][y]);
  83.  
  84. int ans=-; full--;
  85. FOR(i,,n) FOR(x,,) {
  86. if(d[full][i][x]<) continue;
  87. update(ans, d[full][i][x] - overlap[i][][x][]); //ans累计 枚举尾字串并减去与第一个串的重叠部分
  88. }
  89. if(ans<=) cout<<"2\n"; //题目中明确给出 n>=2
  90. else
  91. cout<<ans<<"\n";
  92. }
  93. int main(){
  94. while(cin>>n && n) {
  95. init();
  96. solve();
  97. }
  98. return ;
  99. }

【暑假】[深入动态规划]UVa 10618 Fun Game的更多相关文章

  1. 【暑假】[深入动态规划]UVa 10618 Fixing the Great Wall

    UVa 10618 Fixing the Great Wall 题目:  http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=361 ...

  2. 【暑假】[深入动态规划]UVa 10618 Tango Tango Insurrection

    UVa 10618 Tango Tango Insurrection 题目: Problem A: Tango Tango Insurrection You are attempting to lea ...

  3. 【暑假】[深入动态规划]UVa 10618 The Bookcase

    UVa 12099  The Bookcase 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=42067 思路:    ...

  4. 【暑假】[深入动态规划]UVa 1628 Pizza Delivery

    UVa 1628 Pizza Delivery 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=51189 思路:    ...

  5. 【暑假】[深入动态规划]UVa 1380 A Scheduling Problem

     UVa 1380 A Scheduling Problem 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=41557 ...

  6. 【暑假】[深入动态规划]UVa 12170 Easy Climb

    UVa 12170 Easy Climb 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=24844 思路:  引别人一 ...

  7. 【暑假】[深入动态规划]UVa 1627 Team them up!

    UVa 1627 Team them up! 题目: Team them up! Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Forma ...

  8. 【暑假】[深入动态规划]UVa 1412 Fund Management

    UVa 1412 Fund Management 题目: UVA - 1412 Fund Management Time Limit: 3000MS   Memory Limit: Unknown   ...

  9. ACM - 动态规划 - UVA 1347 Tour

    UVA 1347 Tour 题解 题目大意:有 \(n\) 个点,给出点的 \(x\).\(y\) 坐标.找出一条经过所有点一次的回路,从最左边的点出发,严格向右走,到达最右点再严格向左,回到最左点. ...

随机推荐

  1. eclipse(Version: Neon Release (4.6.0))安装hibernate tools

    这里需要说明的是,hibernate tools是jboss推出的. eclipse——>Eclipse Marketplace... 输入jboss-tools进行搜索 选择jboss too ...

  2. 用in判断input中的placeholder属性是否在这个对象里

    <input id="test"> var ele = document.getElementById("test"); if("plac ...

  3. Eclipse console文本换行

    Eclipse换行主要有3个方面 格式化时编辑器文本换行 源代码注释文本换行 Eclipse控制台console显示文本换行 1和2参考 http://hi.baidu.com/ae6623/item ...

  4. 常用汇编命令&&OD命令总结

    汇编32位CPU所含有的寄存器有: 4个数据寄存器(EAX.EBX.ECX和EDX)对低16位数据的存取,不会影响高16位的数据.这些低16位寄存器分别命名为:AX.BX.CX和DX,它和先前的CPU ...

  5. python语法-[with来自动释放对象]

    python语法-[with来自动释放对象] http://www.cnblogs.com/itech/archive/2011/01/13/1934779.html 一 with python中的w ...

  6. ECSHOP报错误Deprecated: preg_replace(): The /e modifier is depr

    http://www.ecshoptemplate.com/article-1850.html

  7. iOS开发笔记--宏定义的黑魔法 - 宏菜鸟起飞手册

    宏定义在C系开发中可以说占有举足轻重的作用.底层框架自不必说,为了编译优化和方便,以及跨平台能力,宏被大量使用,可以说底层开发离开define将寸步难行.而在更高层级进行开发时,我们会将更多的重心放在 ...

  8. Cygwin安装时,选择163的源后出错:Unable to get setup.ini from <http://mirrors.163.com/cygwin/>

    [问题] 折腾: [记录]Cygwin下把make从v3.82换成v3.81 期间,选择了163的源,结果出错: Cygwin Setup Unable to get setup.ini from & ...

  9. Android TextView结合SpannableString使用

    super.onCreate(savedInstanceState); TextView txtInfo = new TextView(this); SpannableString ss = new ...

  10. 非常实用的15款开源PHP类库

    PHP库给开发者提供了一个标准接口,它帮助开发者在PHP里充分利用面向对象编程.这些库为特定类型的内置功能提供了一个标准的API,允许类可以与PHP引擎进行无缝的交互.此外,开发者使用这些类库还可以简 ...