容易发现有了交换相邻字符的操作后,只要字符串所含有的字符种类和数量相同其就是等价的。这样的状态只有n^3级别,将其抽象成点子串变换抽象成边后就是求最长路径了,缩点dp解决。

  码量巨大,不是很明白要怎样才能用3k写完。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 55
#define P 100000000000000000LL
unsigned long long C[N][N];
int n,m,p[N*N*N],t=,tmp[];
int dfn[N*N*N],low[N*N*N],stk[N*N*N],SET[N*N*N],top=,cnt=;
bool flag[N*N*N];
char s[N],s2[N];
vector<int> ele[N*N*N];
struct magic{int n,a,b,c,x,y,z;}a[N<<];
struct data{int to,nxt;}edge[N*N*N*N];
struct biginteger
{
unsigned long long x,y;
bool operator <(const biginteger&a) const
{
return x==a.x?y<a.y:x<a.x;
}
bool operator >(const biginteger&a) const
{
return x==a.x?y>a.y:x>a.x;
}
biginteger operator +(const biginteger&a) const
{
biginteger v=(biginteger){x,y};
v.x+=a.x;v.y+=a.y;
if (v.y>=P) v.x++,v.y-=P;
return v;
}
biginteger operator *(const unsigned long long&a) const
{
unsigned long long v[]={};int n=;
biginteger tmp=(biginteger){x,y};
while (tmp.y) v[++n]=tmp.y%,tmp.y/=;
if (tmp.x)
{
n=;
while (tmp.x) v[++n]=tmp.x%,tmp.x/=;
}
for (int i=;i<=n;i++) v[i]=v[i]*a;
for (int i=;i<=n;i++)
v[i+]+=v[i]/,v[i]%=;
while (v[n+]) n++,v[n+]+=v[n]/,v[n]%=;
for (int i=;i>=;i--) tmp.y=tmp.y*+v[i];
for (int i=n;i>=;i--) tmp.x=tmp.x*+v[i];
return tmp;
}
}value[N*N*N],V[N*N*N],f[N*N*N];
int trans(int x,int y,int z){return x*(n+)*(n+)+y*(n+)+z+;}
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
void tarjan(int k)
{
dfn[k]=low[k]=++cnt;
flag[k]=;stk[++top]=k;
for (int i=p[k];i;i=edge[i].nxt)
if (!dfn[edge[i].to]) tarjan(edge[i].to),low[k]=min(low[k],low[edge[i].to]);
else if (flag[edge[i].to]) low[k]=min(low[k],dfn[edge[i].to]);
if (dfn[k]==low[k])
{
t++;
while (stk[top]!=k)
{
SET[stk[top]]=t;
ele[t].push_back(stk[top]);
V[t]=V[t]+value[stk[top]];
flag[stk[top]]=;
top--;
}
SET[k]=t;ele[t].push_back(k);V[t]=V[t]+value[k];flag[k]=;top--;
}
}
namespace newgraph
{
int n,t=,p[N*N*N]={},degree[N*N*N],q[N*N*N];
struct data{int to,nxt;}edge[N*N*N*N];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
void topsort()
{
int head=,tail=;for (int i=;i<=n;i++) if (!degree[i]) q[++tail]=i;
while (tail<n)
{
int x=q[++head];
for (int i=p[x];i;i=edge[i].nxt)
{
degree[edge[i].to]--;
if (!degree[edge[i].to]) q[++tail]=edge[i].to;
}
}
}
void solve()
{
topsort();
for (int i=n;i>=;i--)
{
for (int j=p[q[i]];j;j=edge[j].nxt)
f[q[i]]=max(f[q[i]],f[edge[j].to]);
f[q[i]]=f[q[i]]+V[q[i]];
}
}
}
void rebuild()
{
memset(flag,,sizeof(flag));
for (int i=;i<=t;i++)
{
for (int j=;j<ele[i].size();j++)
for (int k=p[ele[i][j]];k;k=edge[k].nxt)
if (!flag[edge[k].to]&&SET[edge[k].to]!=i)
{
flag[edge[k].to]=;
newgraph::addedge(i,SET[edge[k].to]);
newgraph::degree[SET[edge[k].to]]++;
}
for (int j=;j<ele[i].size();j++)
for (int k=p[ele[i][j]];k;k=edge[k].nxt)
flag[edge[k].to]=;
}
newgraph::n=t;
}
int main()
{
n=read(),m=read();
for (int i=;i<=m;i++)
{
scanf("%s",s+);scanf("%s",s2+);
a[i].n=strlen(s+);
for (int j=;j<=a[i].n;j++)
if (s[j]=='A') a[i].a++;
else if (s[j]=='B') a[i].b++;
else if (s[j]=='C') a[i].c++;
for (int j=;j<=a[i].n;j++)
if (s2[j]=='A') a[i].x++;
else if (s2[j]=='B') a[i].y++;
else if (s2[j]=='C') a[i].z++;
if (a[i].a==a[i].x&&a[i].b==a[i].y&&a[i].c==a[i].z) a[i].a=a[i].b=a[i].c=n+;
}
C[][]=;
for (int i=;i<=n;i++)
{
C[i][]=C[i][i]=;
for (int j=;j<i;j++)
C[i][j]=C[i-][j-]+C[i-][j];
}
for (int i=;i<=n;i++)
for (int j=;j<=n-i;j++)
for (int k=;k<=n-i-j;k++)
{
value[trans(i,j,k)]=(biginteger){,C[n][i]};
value[trans(i,j,k)]=value[trans(i,j,k)]*C[n-i][j];
value[trans(i,j,k)]=value[trans(i,j,k)]*C[n-i-j][k];
for (int x=;x<=m;x++)
if (i>=a[x].a&&j>=a[x].b&&k>=a[x].c&&n-i-j-k>=a[x].n-a[x].a-a[x].b-a[x].c)
addedge(trans(i,j,k),trans(i-a[x].a+a[x].x,j-a[x].b+a[x].y,k-a[x].c+a[x].z));
}
t=;
for (int i=;i<=n;i++)
for (int j=;j<=n-i;j++)
for (int k=;k<=n-i-j;k++)
if (!dfn[trans(i,j,k)]) tarjan(trans(i,j,k));
rebuild();
newgraph::solve();
biginteger ans=(biginteger){,};
for (int i=;i<=t;i++) ans=max(ans,f[i]);
if (ans.x)
{
cout<<ans.x;
int x=;
while (ans.y) tmp[++x]=ans.y%,ans.y/=;
for (int i=;i>=;i--) cout<<tmp[i];
}
else cout<<ans.y;
return ;
}

#35 string(缩点+动态规划)的更多相关文章

  1. [NOI.AC#35]string 缩点+拓扑排序

    链接 因为有交换相邻字母,因此给你字符串就相当于给你了这个字符串的所有排列 把等价的串映射到整数范围,再根据 \(m\) 种魔法连边,缩点后在 DAG 上DP即可 无耻地用了int128 #inclu ...

  2. Codeforces #541 (Div2) - E. String Multiplication(动态规划)

    Problem   Codeforces #541 (Div2) - E. String Multiplication Time Limit: 2000 mSec Problem Descriptio ...

  3. BZOJ1179 [Apio2009]Atm Tarjan 强连通缩点 动态规划

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1179 题意概括 有一个有向图,每一个节点有一个权值,其中有一些结束点. 现在,你要从S出发,到达任 ...

  4. ACM学习历程—HDU2476 String painter(动态规划)

    http://acm.hdu.edu.cn/showproblem.php?pid=2476 题目大意是给定一个起始串和一个目标串,然后每次可以将某一段区间染成一种字符,问从起始串到目标串最少需要染多 ...

  5. Number String(HDU 4055,动态规划递推,前缀和优化)

    点击加号查看代码 #include<bits/stdc++.h>//前缀和优化版本,不易理解 using namespace std; #define ll long long ; ; l ...

  6. JS字符串格式化函数 string.format

    原生JS写的仿C#的字符串format函数,在此基础上又增加了便于JS使用的字面量对象参数. 参照C#中的规则,调用的时候会检测字符串格式,如果字符串格式不规范,或者传入的参数为null或undefi ...

  7. string.Format出现异常"输入的字符串格式有误"的解决方法

    string.Format出现异常"输入的字符串格式有误"的解决方法 今天在做项目时,碰到一个很奇怪的问题,我使用string.Format居然报“输入的字符串格式有误”的错误,我 ...

  8. python中string模块各属性以及函数的用法

    任何语言都离不开字符,那就会涉及对字符的操作,尤其是脚本语言更是频繁,不管是生产环境还是面试考验都要面对字符串的操作.     python的字符串操作通过2部分的方法函数基本上就可以解决所有的字符串 ...

  9. java String常见的处理

    import java.util.Arrays; class Demo5 { public static void main(String [] args) { String name1=" ...

随机推荐

  1. Android 给双ListView组织数据源

    需求:现有这样一套原始数据{“A”,"B","C","D","B","A","B" ...

  2. jqgrid 设置冻结列

    有时,jqgrid表格的列非常多,而表格的宽度值是固定的,我们需要在表格底部出现滚动条,并且固定前面几个列作为数据参照项,如何实现? 需要用的jqgrid冻结列,步骤如下: 1)设置需要冻结的列属性, ...

  3. JS设置cookie、读取cookie、删除cookie(转载)

    JavaScript是运行在客户端的脚本,因此一般是不能够设置Session的,因为Session是运行在服务器端的.而cookie是运行在客户端的,所以可以用JS来设置cookie.假设有这样一种情 ...

  4. Android开发四大组件之Service(具体解释篇)

    Android开发之四大组件--Service 一.Service 简单介绍 Service是android系统中的四大组件之中的一个(Activity.Service.BroadcastReceiv ...

  5. Hadoop Version History and Feature

    Versions and Features Hadoop has seen significant interest over the past few years. This has led to ...

  6. excel的宏与VBA入门(三)——流程控制

    一.条件控制IF if 逻辑表达式 then 语句块 end if 带else的if语句: If 逻辑表达式1 Then 语句块1 ElseIf 逻辑表达式2 Then 语句块2 ElseIf 逻辑表 ...

  7. 委托、多播委托(MulticastDelegate)

    委托.多播委托(MulticastDelegate) 多播委托(MulticastDelegate)继承自 Delegate ,表示多路广播委托:即,其调用列表中可以拥有多个元素的委托.实际上,我们自 ...

  8. stl源码剖析 详细学习笔记deque(3)

    protected: typedef simple_alloc<value_type,Alloc> data_allocator; //用来配置元素的alloc typedef simpl ...

  9. Spring+SpringMVC+MyBatis整合基础篇

    基础篇 Spring+SpringMVC+MyBatis+easyUI整合基础篇(一)项目简介 Spring+SpringMVC+MyBatis+easyUI整合基础篇(二)牛刀小试 Spring+S ...

  10. 杂谈---这些大忌,你在面试的时候发生过吗?(NO.1)

              面试是大部分人的人生当中难免会遇到的一件事,那么具体在面试当中有哪些忌讳呢? 说到面试,在这里尤其特指技术岗位的面试,很多时候,结果并不仅仅取决于你的技术广度与深度,亦或是你的笔试 ...