博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
#35 string(缩点+动态规划)
阅读量:4648 次
发布时间:2019-06-09

本文共 3092 字,大约阅读时间需要 10 分钟。

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

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

#include
#include
#include
#include
#include
#include
#include
using namespace std;int read(){ int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') { if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f;}#define N 55#define P 100000000000000000LLunsigned long long C[N][N];int n,m,p[N*N*N],t=0,tmp[20];int dfn[N*N*N],low[N*N*N],stk[N*N*N],SET[N*N*N],top=0,cnt=0;bool flag[N*N*N];char s[N],s2[N];vector
ele[N*N*N];struct magic{ int n,a,b,c,x,y,z;}a[N<<1];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
(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[40]={ 0};int n=0; biginteger tmp=(biginteger){x,y}; while (tmp.y) v[++n]=tmp.y%10,tmp.y/=10; if (tmp.x) { n=17; while (tmp.x) v[++n]=tmp.x%10,tmp.x/=10; } for (int i=1;i<=n;i++) v[i]=v[i]*a; for (int i=1;i<=n;i++) v[i+1]+=v[i]/10,v[i]%=10; while (v[n+1]) n++,v[n+1]+=v[n]/10,v[n]%=10; for (int i=17;i>=1;i--) tmp.y=tmp.y*10+v[i]; for (int i=n;i>=18;i--) tmp.x=tmp.x*10+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+1)*(n+1)+y*(n+1)+z+1;}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]=1;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]]=0; top--; } SET[k]=t;ele[t].push_back(k);V[t]=V[t]+value[k];flag[k]=0;top--; }}namespace newgraph{ int n,t=0,p[N*N*N]={ 0},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=0,tail=0;for (int i=1;i<=n;i++) if (!degree[i]) q[++tail]=i; while (tail
=1;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,0,sizeof(flag)); for (int i=1;i<=t;i++) { for (int j=0;j
=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=0; for (int i=0;i<=n;i++) for (int j=0;j<=n-i;j++) for (int k=0;k<=n-i-j;k++) if (!dfn[trans(i,j,k)]) tarjan(trans(i,j,k)); rebuild(); newgraph::solve(); biginteger ans=(biginteger){ 0,0}; for (int i=1;i<=t;i++) ans=max(ans,f[i]); if (ans.x) { cout<
=1;i--) cout<

 

转载于:https://www.cnblogs.com/Gloid/p/9613467.html

你可能感兴趣的文章
sqlserver 插入数据时异常,仅当使用了列列表并且 IDENTITY_INSERT 为 ON 时,才能为表'XXXXX.dbo.XXXXXXXXX'中的标识列指定显式值。...
查看>>
PS 滤镜算法原理——染色玻璃
查看>>
python之os模块
查看>>
yii2 刷新缓存(刷新模型缓存)
查看>>
SecureCRT突然卡死的问题
查看>>
DevExpress.XtraGrid.Views.Grid.GridView 选中行焦点的滚动条的位置
查看>>
Android类参考---Fragment(五)
查看>>
【Web动画】SVG 实现复杂线条动画
查看>>
修改mysql数据库默认存储引擎和默认编码
查看>>
[TJOI2009] 战争游戏
查看>>
eclipse error
查看>>
微信小程序运行机制
查看>>
安卓新发布机制----app bundle
查看>>
3. 设计模式之创建模式
查看>>
python学习笔记-day6-【python如何写excel表】
查看>>
Switch的簡化
查看>>
tensorflow学习笔记一:安装调试
查看>>
(转自ztp800201) Android - 自定义标题栏(在标题栏中增加按钮和文本居中)
查看>>
领扣简单版--两数之和(Two Sum)
查看>>
第10月第25天 java annotation
查看>>