容易發現有了交換相鄰字元的操作後,只要字串所含有的字元種類和數量相同其就是等價的。這樣的狀態只有n^3級別,將其抽象成點子串變換抽象成邊後就是求最長路徑了,縮點dp解決。
碼量巨大,不是很明白要怎樣才能用3k寫完。
#include#include#include
#include
#include
#include
#include
using
namespace
std;
intread()
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 magica[n<<1
];struct dataedge[n*n*n*n];
struct
biginteger
bool
operator >(const biginteger&a) const
biginteger
operator +(const biginteger&a) const
; 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
;int n=0
; biginteger tmp=(biginteger);
while (tmp.y) v[++n]=tmp.y%10,tmp.y/=10
;
if(tmp.x)
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)
void addedge(int x,int y)
void tarjan(int
k) set[k]=t;ele[t].push_back(k);v[t]=v[t]+value[k];flag[k]=0;top--;
}}namespace
newgraph
,degree[n*n*n],q[n*n*n];
struct dataedge[n*n*n*n];
void addedge(int x,int y)
void
topsort()}}
void
solve()
}}void
rebuild()
for (int j=0;j)
for (int k=p[ele[i][j]];k;k=edge[k].nxt)
flag[edge[k].to]=0
; }
newgraph::n=t;
}int
main()
c[0][0]=1
;
for (int i=1;i<=n;i++)
for (int i=0;i<=n;i++)
for (int j=0;j<=n-i;j++)
for (int k=0;k<=n-i-j;k++)
;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=1;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=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);
for (int i=1;i<=t;i++) ans=max(ans,f[i]);
if(ans.x)
else cout
}
動態規劃散點筆記
找到問題的共性,找到最優子結構,把複雜的父問題拆分為多個互不影響又可以向下迭代的子問題,這些向下迭代的子問題一定要有邊界,否則死迴圈。多階段決策問題 把乙個問題看作是乙個前後關聯具有鏈狀結構的多階段過程就稱為多階段決策過程,這種問題就稱為多階段決策問題。最優子結構 子問題最優時父問題通過優化選擇後一...
知識點8 動態規劃總結
今天也是為了cc,努力奮鬥的一天 o 前面幾節介紹了動態規劃的相關概念,並求解了一些經典的動態規劃模型。但是在實際碰到新的問題時,初學者總是容易陷入頭腦一片空白 完全無法設計狀態的情況,這是正常現象,因為動態規劃本身就需要經驗的積累和大量做題才能有較大的提公升。不過從上面的經典模型中還是能總結出一些...
C 知識點 動態規劃04
今天這篇博文介紹一下動態規劃。先看下邊的經典問題 最長增長子串 例如 3,2,6,4,5,1 的最長增長子串是 2,4,5.先看一下實現 include include using namespace std void prt vector d 不多,這個問題如果採用暴力方法,就是考慮所有的組合,這...