彻彻底底写到自闭的一个专题。

就是大型分类讨论,压行+宏定义很有优势。

常用滚动数组+哈希表+位运算。当然还有轮廓线。

Formula 1:

经过所有格子的哈密顿回路数。

每个非障碍点必须有且仅有2个插头(含上下左右)。

若左上都没有,那么新建两个插头1和2。

若左上只有一个插头,那么它就向右下方向之一延伸。

若左上都有,那么不建新插头。

如果是左1上2,那么就是形成了一条回路,当且仅当在全图右下角更新答案。

如果都是1,那么就要把右边的两个2改成一对插头,就是把靠右的一个1插头匹配的2插头改为1。

都是2同理。

如果是左2上1,那么就是链接了两个路径,两个插头抵消。

 #include<cstdio>
#define cri const register int
int bl[][],n,m,now,last=,ln,lm,fn,fm,r[]={,,-};long long ans;
int read(){
register char ch=getchar();
while(ch!='*'&&ch!='.')ch=getchar();
return ch=='*';
}
struct hash{
int fir[],l[],to[],cnt;long long v[];
void clear(){
for(int i=;i<;++i)to[i]=-,fir[i]=v[i]=;cnt=;
}
long long &operator[](cri pos){
int i;
for(i=fir[pos%];i&&to[i]!=pos;i=l[i]);
if(!i)l[++cnt]=fir[pos%],to[cnt]=pos,fir[pos%]=i=cnt;
return v[i];
}
}f[];
inline int find(cri st,cri p){return st>>(p-<<)&;}
inline void set(int &st,cri p,cri k){st&=~(<<(p-<<));st|=k<<(p-<<);}
inline int get(cri st,cri p){
int dirc=(find(st,p)==)?:-;
for(int i=p,pl=find(st,i),cnt=r[pl];i&&i<=m+;pl=find(st,i+=dirc),cnt+=r[pl])
if(cnt==)return i;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i)for(int j=;j<=m;++j){
bl[i][j]=read();
if(!bl[i][j])ln=i,lm=j;
if(!fn&&!bl[i][j])fn=i,fm=j;
}f[][]=;
for(int i=;i<=n;++i)bl[i][m+]=;
for(int i=;i<=m;++i)bl[n+][i]=;
for(int i=fn;i<=n;++i){
for(int j=(i==fn)?fm:;j<=m;++j){
last^=;now^=; f[now].clear();
for(int k=;k<=f[last].cnt;++k){
int st=f[last].to[k],p1=find(st,j),p2=find(st,j+);
long long v=f[last].v[k];//printf("%d %d %d %d %d %lld\n",i,j,st,p1,p2,v);
if(bl[i][j]&&(p1||p2))continue;
if(bl[i][j])f[now][st]+=v;
else if(!p1&&!p2){if(!bl[i][j+]&&!bl[i+][j])set(st,j,),set(st,j+,),f[now][st]+=v;}
else if(p1&&!p2){
if(!bl[i+][j])f[now][st]+=v;//,printf("---%d %d %lld %lld\n",i,j,v,f[now][st]);
if(!bl[i][j+])set(st,j+,p1),set(st,j,),f[now][st]+=v;
}
else if(!p1&&p2){
if(!bl[i][j+])f[now][st]+=v;
if(!bl[i+][j])set(st,j,p2),set(st,j+,),f[now][st]+=v;
}
else if(p1==&&p2==){if(i==ln&&j==lm)ans+=v;}
else if(p2==&&p1==)set(st,j,),set(st,j+,),f[now][st]+=v;
else if(p1==&&p2==)set(st,get(st,j+),),set(st,j,),set(st,j+,),f[now][st]+=v;
else if(p1==&&p2==)set(st,get(st,j),),set(st,j,),set(st,j+,),f[now][st]+=v;
}
}
for(int i=;i<=f[now].cnt;++i)f[now].to[i]<<=;
}
printf("%lld\n",ans);
}

当时我还不会压行

CITY

和上面同理,只不过限制了插头方向。

 #include<cstdio>
#define int long long
#define mod 54321
int n,m,bl[][],ref[],fn,fm,ln,lm,last=,now,tf[]={,,-};long long ans;
int read(){
register char ch=getchar();
while(ch!='.'&&ch!='#'&&ch!='-'&&ch!='|')ch=getchar();
return ref[ch];
}
struct hash{
int fir[mod],l[mod],to[mod],cnt;long long v[mod];
void clear(){for(int i=;i<mod;++i)fir[i]=v[i]=,to[i]=-;cnt=;}
long long &operator[](int p){
int i;
for(i=fir[p%mod];i&&to[i]!=p;i=l[i]);
if(!i)l[++cnt]=fir[p%mod],fir[p%mod]=i=cnt,to[cnt]=p;
return v[i];
}
}f[];
int find(int st,int p){return st>>(p-<<)&;}
void set(int &st,int p,int k){st&=~(<<(p-<<));st|=k<<(p-<<);}
void reset(int &st,int p){
for(int i=p,pl=find(st,i),di=tf[find(st,p)],cnt=di;i&&i<=m+;i+=di,pl=find(st,i),cnt+=tf[pl])
if(!cnt){set(st,i,pl==?:);return;}
}
main(){
scanf("%lld%lld",&n,&m);ref['#']=;ref['-']=;ref['|']=;
for(int i=;i<=n;++i)for(int j=;j<=m;++j){
bl[i][j]=read();
if(!bl[i][j])ln=i,lm=j;
if(!bl[i][j]&&!fn)fn=i,fm=j;
}
f[][]=;
for(int i=;i<=n;++i)bl[i][m+]=;
for(int i=;i<=m;++i)bl[n+][i]=;
for(int i=fn;i<=n;++i){
for(int j=(i==fn?fm:);j<=m;++j){
last^=;now^=;f[now].clear();
for(int k=;k<=f[last].cnt;++k){
int st=f[last].to[k],p1=find(st,j),p2=find(st,j+);long long v=f[last].v[k];//printf("%d %d %d %d %d %lld\n",i,j,st,p1,p2,v);
if(((bl[i][j]&)&&p2)||((bl[i][j]&)&&p1))continue;
if(bl[i][j]==){if(!p1&&!p2)f[now][st]+=v;continue;}
if(bl[i][j]==){if((!(bl[i+][j]&))&&p2&&!p1)set(st,j+,),set(st,j,p2),f[now][st]+=v;continue;}
if(bl[i][j]==){if((!(bl[i][j+]&))&&p1&&!p2)set(st,j,),set(st,j+,p1),f[now][st]+=v;continue;}
if(!p1&&!p2){if(!(bl[i][j+]&)&&!(bl[i+][j]&))set(st,j,),set(st,j+,),f[now][st]+=v;}
else if(p1&&!p2){
if(!(bl[i+][j]&))f[now][st]+=v;
if(!(bl[i][j+]&))set(st,j,),set(st,j+,p1),f[now][st]+=v;
}
else if(p2&&!p1){
if(!(bl[i][j+]&))f[now][st]+=v;
if(!(bl[i+][j]&))set(st,j+,),set(st,j,p2),f[now][st]+=v;
}
else if(p1==&&p2==){if(i==ln&&j==lm)ans+=v;}
else if(p2==&&p1==)set(st,j,),set(st,j+,),f[now][st]+=v;
else if(p1==&&p2==)reset(st,j+),set(st,j,),set(st,j+,),f[now][st]+=v;
else if(p1==&&p2==)reset(st,j),set(st,j,),set(st,j+,),f[now][st]+=v;
}
}
for(int j=;j<=f[now].cnt;++j)f[now].to[j]<<=;
}
printf("%lld\n",ans);
}

我依旧不会压行

邮递员

依旧同理。注意n或m=1。

 #include<cstdio>
#define hash_mod 54321
#define int_mod 100000000000000ll
#define cri const register int
int n,m;
struct gj{
long long x[];
inline void clear(){x[]=x[]=x[]=x[]=x[]=;}
inline void print(){
int i;
for(i=;i>=;--i)if(x[i]){printf("%lld",x[i]);break;}
for(i--;i>=;--i)printf("%014lld",x[i]);puts("");
}
inline void operator+=(const gj &b){
for(int i=;i>=;--i)x[i]+=b.x[i];
for(int i=;i<=;++i)x[i+]+=x[i]/int_mod,x[i]%=int_mod;
}
}ans;
struct hash_map{
int fir[],l[],to[],cnt;gj v[];
void clear(){
for(int i=;i<;++i)fir[i]=,v[i].clear(),to[i]=-;
cnt=;
}
gj &operator[](const int key){
int pos=key%hash_mod,i;
for(i=fir[pos];to[i]!=key&&i;i=l[i]);
if(!i)to[++cnt]=key,l[cnt]=fir[pos],i=fir[pos]=cnt,v[cnt].clear();
return v[i];
}
}hash[];
inline int find(cri st,cri pos){return st>>(pos-<<)&;}
inline int get(cri st,cri pos){
int cnt=,dirc=(find(st,pos)==)?:-;
for(int i=pos,plug=find(st,pos);i&&i<=m+;plug=find(st,i+=dirc)){
if(plug==)cnt++;else if(plug==)cnt--;
if(cnt==)return i;
}
return -;
}
inline void set(int &st,cri pos,cri kind){
st|=<<(pos-<<);st^=<<(pos-<<);
st|=kind<<(pos-<<);
}
void DP(cri x,cri y){
int now=(x-)*m+y&,last=now^,tot=hash[last].cnt;
hash[now].clear();
for(int i=;i<=tot;++i){
int st=hash[last].to[i],plug1=find(st,y),plug2=find(st,y+);
gj v=hash[last].v[i];//printf("%d %d %d %d %d ",x,y,st,plug1,plug2);v.print();
if(get(st,y)==-||get(st,y+)==-)continue;
if(!plug1&&!plug2){if(y!=m&&x!=n)set(st,y,),set(st,y+,),hash[now][st]+=v;}
else if(plug1&&!plug2){
if(x!=n)hash[now][st]+=v;
if(y!=m)set(st,y,),set(st,y+,plug1),hash[now][st]+=v;
}
else if(!plug1&&plug2){
if(y!=m)hash[now][st]+=v;
if(x!=n)set(st,y,plug2),set(st,y+,),hash[now][st]+=v;
}
else if(plug1==&&plug2==){if(x==n&&y==m)ans+=v;}
else if(plug1==&&plug2==)set(st,y,),set(st,y+,),hash[now][st]+=v;
else if(plug1==&&plug2==)
set(st,get(st,y+),),set(st,y,),set(st,y+,),hash[now][st]+=v;
else if(plug1==&&plug2==)
set(st,get(st,y),),set(st,y,),set(st,y+,),hash[now][st]+=v;
}//printf("%d--%d--%d\n",x,y,hash[now].cnt);
}
int main(){
scanf("%d%d",&n,&m);
hash[].clear();hash[][].x[]=;
if(n==||m==){printf("");return ;}
if(n<m)n^=m,m^=n,n^=m;
for(int i=;i<=n;++i){
for(int j=;j<=m;++j)DP(i,j);
if(i!=n){
int now=(i*m)&,tot=hash[now].cnt;
for(int i=;i<=tot;++i)hash[now].to[i]<<=;
}
}
if(ans.x[]==){puts("");return ;}
ans+=ans;ans.print();
}

我还是不会压行

地板

这个插头不太一样。

对于一个L型,其实只有转弯前和转弯后两种状态。分别做1,2。

空格的话,可以把这个点作为拐角,往右下两个方向延伸出两个已经拐弯的插头。

如果只有一个1插头,那么可以选择转弯与否。

如果两个1插头碰在一起,那么它们就在这里转弯,互相抵消。

如果只有一个2插头,那么就延伸就好了。

 #include<cstdio>
#include<cstring>
using namespace std;
#define mod 20110520
#define ad(a,b) add(dp[nx][set(set(st,j,a),j+1,b)],v)
void add(int &a,int b){a+=b;if(a>mod)a-=mod;}
int n,m,dp[][];char s[][];bool a[][];
int find(int st,int num){return st>>num*-&;}
int set(int st,int num,int v){return st^st&<<num*-^v<<num*-;}
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i)scanf("%s",s[i]+);
if(n<m){
for(int i=;i<=n;++i)for(int j=;j<=m;++j)a[j][i]=s[i][j]=='_';
n^=m^=n^=m;
}else for(int i=;i<=n;++i)for(int j=;j<=m;++j)a[i][j]=s[i][j]=='_';
int nw=,nx=;dp[][]=;
for(int i=;i<=n;++i){
for(int j=;j<=m;++j){
nw^=;nx^=;
for(int st=;st<<<m*+;++st)if(dp[nw][st]){
int l=find(st,j),u=find(st,j+),v=dp[nw][st];dp[nw][st]=;
if(!a[i][j]){if(l==&&u==)ad(,);continue;}
if(l==&&u==)ad(,),ad(,),ad(,);
else if(l==&&u==)ad(,),ad(,);
else if(l==&&u==)ad(,),ad(,);
else if(l==&&u==)ad(,);
else if(l==&&u==)ad(,),ad(,);
else if(l==&&u==)ad(,),ad(,);
}
}
nw^=;nx^=;
for(int st=;st<<<m*;++st)dp[nx][st<<]=dp[nw][st];
for(int st=;st<<<m*+;++st)dp[nw][st]=;
}printf("%d\n",dp[nx][]);
}

然后我开始压行

标识设计

题意补充:笔画的宽度一定是1,棋盘不用占满,L型不能旋转。

因为不能旋转,所以只有一种插头。

但是不能占满,这个好说,只不过多了一种如果这个格子是空格的话也可以不增加新插头。

然后就退化一下上一题的代码,不过区分一下已经写了几个L就行。

 #include<cstdio>
#include<cstring>
using namespace std;
int dp[][],n,m,w[][],stc,cts[],ans=-,nw,nx=;
int find(int st,int num){return st>>num*&;}
void sch(int al,int st){if(al==m+)cts[++stc]=st;else for(int i=;i<=;++i)sch(al+,st|i<<al*);}
int set(int st,int num,int v){return st^st&<<num*^v<<num*;}
void maxi(int &a,int b){if(a<b)a=b;}
int rmat(int st,int p){for(int i=p+;;++i)if(find(st,i)==)return st-(<<i*);}
int lmat(int st,int p){for(int i=p-;;--i)if(find(st,i)==)return st+(<<i*);}
#define upd(a,b) maxi(dp[nx][set(set(st,j-1,a),j,b)],v)
int main(){
scanf("%d%d",&n,&m);memset(dp,0xa0,sizeof dp);
for(int i=;i<=n;++i)for(int j=;j<=m;++j)scanf("%d",&w[i][j]);
dp[nx][]=;sch(,);
for(int i=;i<=n;++i){
for(int j=;j<=m;++j){
nw^=;nx^=;memset(dp[nx],0xa0,sizeof dp[nx]);
for(int p=,st;p<=stc;++p)if(dp[nw][st=cts[p]]>=-){
int p1=find(st,j-),p2=find(st,j),v=dp[nw][st]+w[i][j];
if(p1==&&p2==)upd(,),maxi(dp[nx][st],dp[nw][st]);
if(p1==&&p2==)if(set(set(st,j-,),j,)==)maxi(ans,v);
if(p1==&&p2==)upd(,);
if((p1^p2)==)upd(,),upd(,);
if((p1^p2)==)upd(,),upd(,);
if(p1==&&p2==)maxi(dp[nx][rmat(set(set(st,j-,),j,),j)],v);
if(p1==&&p2==)maxi(dp[nx][lmat(set(set(st,j-,),j,),j)],v);
}
}
nw^=;nx^=;memset(dp[nx],0xa0,sizeof dp[nx]);
for(int p=,st;p<=stc;++p)if(cts[p]<<<m<<m)dp[nx][cts[p]<<]=dp[nw][cts[p]];
}printf("%d\n",ans);
}

压行越发熟练

Park II

毒瘤界的巅峰。

理论上有3个插头,16种情况,但是情况很多重复,所以可以压成9类。

因为这一题是路径而不是回路,而且也不用占满。

为了处理路径的问题,需要引进一种新的插头,就是一端为路径的端点,另一端在轮廓线上的插头,学习LadyLex称之为独立插头3。

所有插头合并情况如下:

1,两个空格:这个格子可以不放,也可以作为拐角放一对12插头,也可以作为路径端点在右下方向之一放一个3插头。

2,两个1/2:与回路的题做法一致。

3,两个3:如果没有其它插头,那么你已经让两个自由端联通了,如果不存在其它插头,那么就可以更新答案。

4,左1上2:在回路题里这样会形成回路,但是路径题不允许回路,所以不做操作。(也就是在代码里不用写出来这种情况)

5,左2上1:与回路的题做法一致。

6,只有一个插头:另一个可以向右下方向之一转弯。

7,只有一个3插头:它可以结束了,作为路径端点,这样的话如果没有其它插头就可以更新答案了。

8,只有一个1/2插头:它可以结束了,作为路径端点,这样的话与1/2配对的2/1插头应该变成孤立的3插头。

9,有一个1/2插头,另一个是3插头:它们匹配了,这样的话与1/2配对的2/1插头应该变成孤立的3插头。
没有其它情况了。

如果宏定义+压行足够优秀,这道题不一定会比前面的题长。

 #include<cstdio>
#include<cstring>
using namespace std;
void maxi(int &a,int b){if(a<b)a=b;}
int set(int st,int p,int v){return st^st&<<p*^v<<p*;}
int get(int st,int p){return st>>p*&;}
int mat(int st,int p,int v,int d,int g,int c=){
for(;;p+=d)if(get(st,p)==g+){c--;if(!c)return st+(v-g-<<p*);}
else if(get(st,p)==(g^)+)c++;
}
int dp[][],w,n,m,nx,nw=,ans,c[],ac[];
#define up(a,b) maxi(dp[nx][set(set(st,j-1,a),j,b)],v)
#define cl set(set(st,j-1,0),j,0)
int main(){
scanf("%d%d",&n,&m);
memset(dp,0xa0,sizeof dp);dp[nx][]=;
for(int i=;i<=n;++i){
for(int j=;j<=m;++j){
nw^=;nx^=;memset(dp[nx],0xa0,sizeof dp[nx]);scanf("%d",&w);
for(int st=;st<<<m*+;++st)if(dp[nw][st]>-){
int p1=get(st,j-),p2=get(st,j),v=dp[nw][st]+w;
for(int q=;q<;++q)c[q]=;c[p1]++;c[p2]++;
if(c[]==)up(,),up(,),up(,),maxi(dp[nx][st],v-w);
if(c[]==)maxi(dp[nx][mat(cl,j,,,)],v);
if(c[]==)maxi(dp[nx][mat(cl,j,,-,)],v);
if(c[]==)if(!cl)maxi(ans,v);
if(p1==&p2==)up(,);
if(c[]==)up(p1|p2,),up(,p1|p2);
if(c[]&c[])if(!cl)maxi(ans,v);
if(c[]&(c[]|c[]))maxi(dp[nx][mat(cl,j,,,)],v);
if(c[]&(c[]|c[]))maxi(dp[nx][mat(cl,j,,-,)],v);
}
}
nx^=;nw^=;memset(dp[nx],0xa0,sizeof dp[nx]);
for(int st=;st<<<m*;++st)dp[nx][st<<]=dp[nw][st];
}printf("%d\n",ans);
}

毒瘤巅峰的压行巅峰

游览计划

插头dp的话不是很好做,开5种插头记录联通块就行了。

我没有这么写,我写的是最小斯坦纳树。

好像没听过很高端?实际上就是dp。

dp[i][j][st]表式包含(i,j)这个点的一个联通块所覆盖的景点集合为st(状态压缩)。

考虑转移:

首先如果(i,j)就是景点,编号为k,那么dp[i][j][k]=0;

这个点往四周扩展:dp[x][y][st]=min(dp[i][j][st]+w[x][y])

这个点的子集合并:dp[i][j][st]=min(dp[i][j][s1]+dp[i][j][s2]-w[i][j]),其中s1与s2的并集为st。

没了。

但是第一个转移出环了。用原来B组题里的那个SPFA解决循环dp就好了。

记录转移点回溯输出方案。

 #include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int xx[]={,,,-},yy[]={,-,,};
#define tx x+xx[i]
#define ty y+yy[i]
int w[][],n,m,k=,dp[][][],pre[][][],qx[],qy[],iq[][],v[][];
void SPFA(int st,int t=){
for(int i=;i<=n;++i)for(int j=;j<=m;++j)if(dp[i][j][st]<)qx[++t]=i,qy[t]=j,iq[i][j]=;
for(int h=,x,y;x=qx[h],y=qy[h],iq[x][y]=,h<=t;++h)for(int i=;i<;++i)
if(tx&&ty&&tx<=n&&ty<=m&&dp[tx][ty][st]>dp[x][y][st]+w[tx][ty]){
dp[tx][ty][st]=dp[x][y][st]+w[tx][ty];pre[tx][ty][st]=x<<|y<<|st;
if(!iq[tx][ty])iq[qx[++t]=tx][qy[t]=ty]=;
}
}
void dfs(int x,int y,int st){
v[x][y]=;int px=pre[x][y][st]>>,py=pre[x][y][st]>>&,pst=pre[x][y][st]&;
if(!pre[x][y][st])return;
dfs(px,py,pst);if(x==px&&y==py)dfs(px,py,st^pst);
}
int main(){
scanf("%d%d",&n,&m);memset(dp,0x3f,sizeof dp);
for(int i=;i<=n;++i)for(int j=;j<=m;++j)scanf("%d",&w[i][j]);
for(int i=;i<=n;++i)for(int j=;j<=m;++j)if(!w[i][j])dp[i][j][k]=,k<<=;
for(int st=;st<k;++st){
for(int i=;i<=n;++i)for(int j=;j<=m;++j)for(int s=st&st-;s;s=s-&st)
if(dp[i][j][st]>dp[i][j][s]+dp[i][j][st^s]-w[i][j])
dp[i][j][st]=dp[i][j][s]+dp[i][j][st^s]-w[i][j],pre[i][j][st]=i<<|j<<|s;
SPFA(st);
}
for(int i=;i<=n;++i)for(int j=;j<=m;++j)if(!w[i][j]){
dfs(i,j,k-);printf("%d\n",dp[i][j][k-]);
for(int i=;i<=n;++i,puts(""))for(int j=;j<=m;++j)putchar(w[i][j]?(v[i][j]?'o':'_'):'x');
return ;
}
}

难写所以没压行

[专题总结]初探插头dp的更多相关文章

  1. 初探 插头DP

    因为这题,气得我火冒三丈! 这数据是不是有问题啊!我用cin代替scanf后居然就AC了(本来一直卡在Test 18)!导致我调(对)试(排)了一个小时!! UPD:后来细细想想,会不会是因为scan ...

  2. 初探插头dp

    开学那个月学了点新东西,不知道还记不记得了,mark一下 感觉cdq的论文讲的很详细 题主要跟着kuangbin巨做了几道基础的 http://www.cnblogs.com/kuangbin/arc ...

  3. 插头dp初探

    问题描述 插头dp用于解决一类可基于图连通性递推的问题.用插头来表示轮廓线上的连通性,然后根据连通性与下一位结合讨论进行转移. 表示连通性的方法 与字符串循环最小表示不同,这种方法用于给轮廓线上的联通 ...

  4. 插头DP专题

    建议入门的人先看cd琦的<基于连通性状态压缩的动态规划问题>.事半功倍. 插头DP其实是比较久以前听说的一个东西,当初是水了几道水题,最近打算温习一下,顺便看下能否入门之类. 插头DP建议 ...

  5. 插头dp练习

    最近学了插头dp,准备陆续更新插头dp类练习. 学习论文还是cdq那篇<基于连通性状态压缩的动态规划问题>. 基本的想法都讲得很通透了,接下来就靠自己yy了. 还有感谢kuangbin大大 ...

  6. 插头dp

    插头dp 感受: 我觉得重点是理解,算法并不是直接想出怎样由一种方案变成另一种方案.而是方案本来就在那里,我们只是枚举状态统计了答案. 看看cdq的讲义什么的,一开始可能觉得状态很多,但其实灰常简单 ...

  7. HDU 4113 Construct the Great Wall(插头dp)

    好久没做插头dp的样子,一开始以为这题是插头,状压,插头,状压,插头,状压,插头,状压,无限对又错. 昨天看到的这题. 百度之后发现没有人发题解,hust也没,hdu也没discuss...在acm- ...

  8. HDU 4949 Light(插头dp、位运算)

    比赛的时候没看题,赛后看题觉得比赛看到应该可以敲的,敲了之后发现还真就会卡题.. 因为写完之后,无限TLE... 直到后来用位运算代替了我插头dp常用的decode.encode.shift三个函数以 ...

  9. HDU 1693 Eat the Trees(插头DP、棋盘哈密顿回路数)+ URAL 1519 Formula 1(插头DP、棋盘哈密顿单回路数)

    插头DP基础题的样子...输入N,M<=11,以及N*M的01矩阵,0(1)表示有(无)障碍物.输出哈密顿回路(可以多回路)方案数... 看了个ppt,画了下图...感觉还是挺有效的... 参考 ...

随机推荐

  1. 手动启动Oracle服务的.bat文件

    Oracle数据库的基本服务会占用很大的内存,有的程序员会在不用的时候Oracle服务关闭来减少对电脑内存资源的占用. 我在这准备了一个可以开启/关闭Oracle服务的bat文件,希望被采纳!!! 新 ...

  2. zabbix主动模式无法获取网卡和文件系统数据

    zabbix版本为4.2,根据网上教程将zabbixagent设置成主动模式后,将templates中各Items的type改为Zabbix agent (active),同时将Discovery r ...

  3. java8-从Lamda到方法引用和构造引用

    一方法引用概述 经过前面2章Lamda原理引入和Lamda解析,基本就会熟练使用Lamda表达式,这次我们更深入点.来了解一下方法引用. 方法引用是特定Lamda表达式的一种简写,其思路就是能替换La ...

  4. 初学Swoole:PHP7安装Swoole的步骤

    本篇文章给大家带来的内容是关于初学Swoole:PHP7安装Swoole的步骤,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 环境 这里不在使用apache做为web server. ...

  5. c++-多态的学习

    多态的基本介绍 多态基础 面向对象新求 C++编译器提供的多态解决方案 多态意义.多态成立的是三个条件 多态理论基础 多态面试题强化 多态的理解 C++编译器如何实现多态 重载重写重定义 虚析构函数 ...

  6. 「SAP技术」SAP MM 明明有维护源清单,还是不能下PO?

    SAP MM 明明有维护源清单,还是不能下PO? 下午收到用户报错说,创建采购订单失败,报错 :Material ### not included in source list despite sou ...

  7. OS之进程和线程

    1. 线程是程序执行流的最小单元. 一个标准的线程由线程ID,当前指令指针PC,寄存器集合和堆栈组成. 2. 通常意义上,一个进程由一个到多个线程组成,各个线程之间共享程序的的内存空间,包括代码段.数 ...

  8. 【zabbix部署】基于linux安装zabbix监控服务和被监控服务

    环境配置 zabbix_server:10.0.0.1 zabbix_agentd:10.0.0.1,10.0.0.2(暂定) 操作系统:centos7.6 安装环境配置 1. LNMP环境 zabb ...

  9. C语言笔记 03_常量&存储类

    常量 常量是固定值,在程序执行期间不会改变.这些固定的值,又叫做字面量. 常量可以是任何的基本数据类型,比如整数常量.浮点常量.字符常量,或字符串字面值,也有枚举常量. 整数常量 整数常量可以是十进制 ...

  10. sqlalchemy 执行原生sql语句

    from contextlib import contextmanager from sqlalchemy import create_engine, ForeignKey from sqlalche ...