#35 string(缩点+动态规划)
容易发现有了交换相邻字符的操作后,只要字符串所含有的字符种类和数量相同其就是等价的。这样的状态只有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(缩点+动态规划)的更多相关文章
- [NOI.AC#35]string 缩点+拓扑排序
链接 因为有交换相邻字母,因此给你字符串就相当于给你了这个字符串的所有排列 把等价的串映射到整数范围,再根据 \(m\) 种魔法连边,缩点后在 DAG 上DP即可 无耻地用了int128 #inclu ...
- Codeforces #541 (Div2) - E. String Multiplication(动态规划)
Problem Codeforces #541 (Div2) - E. String Multiplication Time Limit: 2000 mSec Problem Descriptio ...
- BZOJ1179 [Apio2009]Atm Tarjan 强连通缩点 动态规划
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1179 题意概括 有一个有向图,每一个节点有一个权值,其中有一些结束点. 现在,你要从S出发,到达任 ...
- ACM学习历程—HDU2476 String painter(动态规划)
http://acm.hdu.edu.cn/showproblem.php?pid=2476 题目大意是给定一个起始串和一个目标串,然后每次可以将某一段区间染成一种字符,问从起始串到目标串最少需要染多 ...
- Number String(HDU 4055,动态规划递推,前缀和优化)
点击加号查看代码 #include<bits/stdc++.h>//前缀和优化版本,不易理解 using namespace std; #define ll long long ; ; l ...
- JS字符串格式化函数 string.format
原生JS写的仿C#的字符串format函数,在此基础上又增加了便于JS使用的字面量对象参数. 参照C#中的规则,调用的时候会检测字符串格式,如果字符串格式不规范,或者传入的参数为null或undefi ...
- string.Format出现异常"输入的字符串格式有误"的解决方法
string.Format出现异常"输入的字符串格式有误"的解决方法 今天在做项目时,碰到一个很奇怪的问题,我使用string.Format居然报“输入的字符串格式有误”的错误,我 ...
- python中string模块各属性以及函数的用法
任何语言都离不开字符,那就会涉及对字符的操作,尤其是脚本语言更是频繁,不管是生产环境还是面试考验都要面对字符串的操作. python的字符串操作通过2部分的方法函数基本上就可以解决所有的字符串 ...
- java String常见的处理
import java.util.Arrays; class Demo5 { public static void main(String [] args) { String name1=" ...
随机推荐
- Android 给双ListView组织数据源
需求:现有这样一套原始数据{“A”,"B","C","D","B","A","B" ...
- jqgrid 设置冻结列
有时,jqgrid表格的列非常多,而表格的宽度值是固定的,我们需要在表格底部出现滚动条,并且固定前面几个列作为数据参照项,如何实现? 需要用的jqgrid冻结列,步骤如下: 1)设置需要冻结的列属性, ...
- JS设置cookie、读取cookie、删除cookie(转载)
JavaScript是运行在客户端的脚本,因此一般是不能够设置Session的,因为Session是运行在服务器端的.而cookie是运行在客户端的,所以可以用JS来设置cookie.假设有这样一种情 ...
- Android开发四大组件之Service(具体解释篇)
Android开发之四大组件--Service 一.Service 简单介绍 Service是android系统中的四大组件之中的一个(Activity.Service.BroadcastReceiv ...
- Hadoop Version History and Feature
Versions and Features Hadoop has seen significant interest over the past few years. This has led to ...
- excel的宏与VBA入门(三)——流程控制
一.条件控制IF if 逻辑表达式 then 语句块 end if 带else的if语句: If 逻辑表达式1 Then 语句块1 ElseIf 逻辑表达式2 Then 语句块2 ElseIf 逻辑表 ...
- 委托、多播委托(MulticastDelegate)
委托.多播委托(MulticastDelegate) 多播委托(MulticastDelegate)继承自 Delegate ,表示多路广播委托:即,其调用列表中可以拥有多个元素的委托.实际上,我们自 ...
- stl源码剖析 详细学习笔记deque(3)
protected: typedef simple_alloc<value_type,Alloc> data_allocator; //用来配置元素的alloc typedef simpl ...
- Spring+SpringMVC+MyBatis整合基础篇
基础篇 Spring+SpringMVC+MyBatis+easyUI整合基础篇(一)项目简介 Spring+SpringMVC+MyBatis+easyUI整合基础篇(二)牛刀小试 Spring+S ...
- 杂谈---这些大忌,你在面试的时候发生过吗?(NO.1)
面试是大部分人的人生当中难免会遇到的一件事,那么具体在面试当中有哪些忌讳呢? 说到面试,在这里尤其特指技术岗位的面试,很多时候,结果并不仅仅取决于你的技术广度与深度,亦或是你的笔试 ...