【暑假】[深入动态规划]UVa 10618 Fun Game
UVa 10618 Fun Game
题目:
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=36035
思路:
一圈人围坐,给出小球的传递序列,求解最少有多少个人。
问题简单化:如果有一排人,单向传递,给出序列求解最少多少人。那么问题就是:求解一个最短序列使得给出的所有序列都是该序列的连续子序列。
再分别解决以下问题:
- 第一个人可以向左向右传递: 每个传递序列有两种情况,分别是正序与逆序。因为不清楚当前序列是向左传还是向右传。
- 传递是一个环:规定将第一个序列正向串作为首序列,累计答案的时候只需要算上重叠部分即可。
- 输入可能是绕过好几圈的情况:如果绕过好几圈,那么其他的字串因已经被包含而舍弃,dp过程不会进行,最后累计ans时ans=len[0]-重叠(s[0][0],s[0][0])即最小循环节的长度。
- 输入保证n>=2:当ans<=1是修改为2
代码:
- #include<iostream>
- #include<cstring>
- #include<vector>
- #include<algorithm>
- #define FOR(a,b,c) for(int a=(b);a<(c);a++)
- using namespace std;
- const int maxn = ;
- const int maxlen= + ;
- struct Node{
- string s,rev;
- bool operator <(const Node& rhs) const{
- return s.size()<rhs.s.size(); //size由小到大
- }
- };
- int n;
- int d[<<maxn][maxn][];
- int overlap[maxn][maxn][][];
- string s[maxn][];
- int len[maxn];
- //return a右 && b左的重叠部分
- int make_overlap(const string& a,const string& b){
- int n1=a.size();
- int n2=b.size();
- FOR(i,,n1) { //找到最小重合点 即返回最大重合长度
- if(n2 + i <= n1) continue;
- bool ok=true;
- for(int j=;i+j<n1;j++)
- if(a[i+j] != b[j]) { ok=false; break; }
- if(ok) return n1-i;
- }
- return ; //无重合
- }
- void init() {
- Node nodes[maxn];
- FOR(i,,n) {
- cin>>nodes[i].s;
- nodes[i].rev=nodes[i].s;
- reverse(nodes[i].rev.begin(),nodes[i].rev.end()); //反转串
- }
- sort(nodes,nodes+n); //sort
- int nn=;
- FOR(i,,n) {
- bool need=true;
- FOR(j,i+,n)
- if(nodes[j].s.find(nodes[i].s) != string::npos ||
- nodes[j].rev.find(nodes[i].s) != string::npos){ //如果被包含则舍弃
- need=false; break;
- }
- if(need) {
- s[nn][]=nodes[i].s;
- s[nn][]=nodes[i].rev;
- len[nn]=s[nn][].size();
- nn++;
- }
- }
- n=nn;
- //构造重叠数组
- FOR(i,,n) FOR(x,,)
- FOR(j,,n) FOR(y,,)
- overlap[i][j][x][y]=make_overlap(s[i][x],s[j][y]);
- }
- inline void update(int& x,int v) {
- if(x< || v<x) x=v;
- }
- void solve() {
- memset(d,-,sizeof(d));
- d[][][]=len[]; //始终把s[0][0]放在首位
- int full=<<n;
- FOR(s,,full)
- FOR(i,,n) FOR(x,,) if(d[s][i][x]>=) //已求过集合中的枚举
- FOR(j,,n) if(!((<<j) & s)) FOR(y,,) //刷表更新的目标枚举
- update(d[s|(<<j)][j][y], d[s][i][x] + len[j]-overlap[i][j][x][y]);
- int ans=-; full--;
- FOR(i,,n) FOR(x,,) {
- if(d[full][i][x]<) continue;
- update(ans, d[full][i][x] - overlap[i][][x][]); //ans累计 枚举尾字串并减去与第一个串的重叠部分
- }
- if(ans<=) cout<<"2\n"; //题目中明确给出 n>=2
- else
- cout<<ans<<"\n";
- }
- int main(){
- while(cin>>n && n) {
- init();
- solve();
- }
- return ;
- }
【暑假】[深入动态规划]UVa 10618 Fun Game的更多相关文章
- 【暑假】[深入动态规划]UVa 10618 Fixing the Great Wall
UVa 10618 Fixing the Great Wall 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=361 ...
- 【暑假】[深入动态规划]UVa 10618 Tango Tango Insurrection
UVa 10618 Tango Tango Insurrection 题目: Problem A: Tango Tango Insurrection You are attempting to lea ...
- 【暑假】[深入动态规划]UVa 10618 The Bookcase
UVa 12099 The Bookcase 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=42067 思路: ...
- 【暑假】[深入动态规划]UVa 1628 Pizza Delivery
UVa 1628 Pizza Delivery 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=51189 思路: ...
- 【暑假】[深入动态规划]UVa 1380 A Scheduling Problem
UVa 1380 A Scheduling Problem 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=41557 ...
- 【暑假】[深入动态规划]UVa 12170 Easy Climb
UVa 12170 Easy Climb 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=24844 思路: 引别人一 ...
- 【暑假】[深入动态规划]UVa 1627 Team them up!
UVa 1627 Team them up! 题目: Team them up! Time Limit: 3000MS Memory Limit: Unknown 64bit IO Forma ...
- 【暑假】[深入动态规划]UVa 1412 Fund Management
UVa 1412 Fund Management 题目: UVA - 1412 Fund Management Time Limit: 3000MS Memory Limit: Unknown ...
- ACM - 动态规划 - UVA 1347 Tour
UVA 1347 Tour 题解 题目大意:有 \(n\) 个点,给出点的 \(x\).\(y\) 坐标.找出一条经过所有点一次的回路,从最左边的点出发,严格向右走,到达最右点再严格向左,回到最左点. ...
随机推荐
- eclipse(Version: Neon Release (4.6.0))安装hibernate tools
这里需要说明的是,hibernate tools是jboss推出的. eclipse——>Eclipse Marketplace... 输入jboss-tools进行搜索 选择jboss too ...
- 用in判断input中的placeholder属性是否在这个对象里
<input id="test"> var ele = document.getElementById("test"); if("plac ...
- Eclipse console文本换行
Eclipse换行主要有3个方面 格式化时编辑器文本换行 源代码注释文本换行 Eclipse控制台console显示文本换行 1和2参考 http://hi.baidu.com/ae6623/item ...
- 常用汇编命令&&OD命令总结
汇编32位CPU所含有的寄存器有: 4个数据寄存器(EAX.EBX.ECX和EDX)对低16位数据的存取,不会影响高16位的数据.这些低16位寄存器分别命名为:AX.BX.CX和DX,它和先前的CPU ...
- python语法-[with来自动释放对象]
python语法-[with来自动释放对象] http://www.cnblogs.com/itech/archive/2011/01/13/1934779.html 一 with python中的w ...
- ECSHOP报错误Deprecated: preg_replace(): The /e modifier is depr
http://www.ecshoptemplate.com/article-1850.html
- iOS开发笔记--宏定义的黑魔法 - 宏菜鸟起飞手册
宏定义在C系开发中可以说占有举足轻重的作用.底层框架自不必说,为了编译优化和方便,以及跨平台能力,宏被大量使用,可以说底层开发离开define将寸步难行.而在更高层级进行开发时,我们会将更多的重心放在 ...
- 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 & ...
- Android TextView结合SpannableString使用
super.onCreate(savedInstanceState); TextView txtInfo = new TextView(this); SpannableString ss = new ...
- 非常实用的15款开源PHP类库
PHP库给开发者提供了一个标准接口,它帮助开发者在PHP里充分利用面向对象编程.这些库为特定类型的内置功能提供了一个标准的API,允许类可以与PHP引擎进行无缝的交互.此外,开发者使用这些类库还可以简 ...