初探插头dp
开学那个月学了点新东西,不知道还记不记得了,mark一下
感觉cdq的论文讲的很详细
题主要跟着kuangbin巨做了几道基础的
http://www.cnblogs.com/kuangbin/archive/2012/10/02/2710343.html
还有几道没做,留着坑
感觉广义括号表示法虽然神奇,但一般最小表示法就够用了吧,感觉最小表示法更直观一点
hdu1693
#include<cstdio>
#include<iostream>
#include<cstring>
typedef long long ll;
using namespace std;
ll f[][][<<];
int a[][];
int n,m,cas; int main()
{
scanf("%d",&cas);
for (int tt=; tt<=cas; tt++)
{
scanf("%d%d",&n,&m);
for (int i=; i<=n; i++)
for (int j=; j<=m; j++)
scanf("%d",&a[i][j]);
printf("Case %d: ",tt);
memset(f,,sizeof(f));
f[][m][]=;
for (int i=; i<=n; i++)
{
for (int j=; j<(<<m); j++)
f[i][][j<<]=f[i-][m][j];
for (int j=; j<=m; j++)
{
for (int st=; st<(<<(m+)); st++)
{
int x=<<j,y=<<(j-);
if (a[i][j])
{
if ((st&x)&&(st&y)) f[i][j][st]=f[i][j-][st^x^y];
else if (!(st&x)&&!(st&y)) f[i][j][st]=f[i][j-][st|x|y];
else f[i][j][st]=f[i][j-][st]+f[i][j-][st^x^y];
}
else {
if (!(st&x)&&!(st&y)) f[i][j][st]=f[i][j-][st];
else f[i][j][st]=;
}
}
}
}
printf("There are %lld ways to eat the trees.\n",f[n][m][]);
}
return ;
}
hdu1693
poj1793(男人八题!)
#include<iostream>
#include<cstdio>
#include<cstring>
typedef long long ll;
const int mo=;
const int maxl=;
using namespace std;
struct node{
int p[mo],nex[maxl],len;
ll st[maxl],f[maxl];
void clr()
{
len=; memset(p,,sizeof(p));
}
void push(ll nw,ll s)
{
int x=nw%mo;
for (int i=p[x];i!=-; i=nex[i])
if (st[i]==nw)
{
f[i]+=s;
return;
}
st[++len]=nw; f[len]=s;
nex[len]=p[x]; p[x]=len;
}
} h[];
int n,m,cas,p,ex,ey;
int a[][],b[],v[]; void get(ll st)
{
for (int i=m; i>=; i--)
{
b[i]=st&;
st>>=;
}
} ll put()
{
memset(v,,sizeof(v)); v[]=;
ll st=; int t=;
for (int i=; i<=m; i++)
{
if (v[b[i]]==-) v[b[i]]=++t;
b[i]=v[b[i]];
st<<=; st|=b[i];
}
return st;
} void shift()
{
for (int i=m;i; i--) b[i]=b[i-];
b[]=;
} void work(int j,int k)
{
if (j==m) shift();
h[p].push(put(),h[-p].f[k]);
} void dp(int i,int j)
{
for (int k=; k<=h[-p].len; k++)
{
get(h[-p].st[k]);
if (!a[i][j])
{
b[j]=b[j-]=; work(j,k);
continue;
}
int x=b[j],y=b[j-];
if (x&&y)
{
if ((x==y&&i==ex&&j==ey)||(x!=y))
{
b[j]=b[j-]=;
if (x!=y)
for (int r=; r<=m; r++) if (b[r]==x) b[r]=y;
work(j,k);
}
}
else if ((x&&!y)||(!x&&y))
{
int r=x+y;
if (a[i][j+]) {b[j]=r; b[j-]=; work(j,k);}
if (a[i+][j]) {b[j-]=r; b[j]=; work(j,k);}
}
else if (a[i][j+]&&a[i+][j])
{
b[j]=b[j-]=m+;
work(j,k);
}
}
} int main()
{
char s[];
scanf("%d%d",&n,&m);
while (n&&m)
{
memset(a,,sizeof(a));
for (int i=; i<=n; i++)
{
scanf("%s",s+);
for (int j=; j<=m; j++)
if (s[j]=='.') a[i][j]=;
}
for (int i=; i<=m; i++)
{
a[n+][i]=;
a[n+][i]=(i>&&i<m)?:;
}
n+=; ex=n; ey=m;
h[].clr();
h[].push(,); p=;
for (int i=; i<=n; i++)
for (int j=; j<=m; j++)
{
p^=; h[p].clr();
dp(i,j);
}
ll ans=;
for (int i=; i<=h[p].len; i++)
ans+=h[p].f[i];
printf("%lld\n",ans);
scanf("%d%d",&n,&m);
}
return ;
}
poj1793
fzu1977
#include<iostream>
#include<cstdio>
#include<cstring>
typedef long long ll;
const int mo=;
const int maxl=;
using namespace std;
struct node{
int p[mo],nex[maxl],len;
ll st[maxl],f[maxl];
void clr()
{
len=; memset(p,,sizeof(p));
}
void push(ll nw,ll s)
{
int x=nw%mo;
for (int i=p[x];i!=-; i=nex[i])
if (st[i]==nw)
{
f[i]+=s;
return;
}
st[++len]=nw; f[len]=s;
nex[len]=p[x]; p[x]=len;
}
} h[];
int n,m,cas,p,ex,ey;
int a[][],b[],v[]; void get(ll st)
{
b[m+]=st&; st>>=;
for (int i=m; i>=; i--)
{
b[i]=st&;
st>>=;
}
} ll put()
{
memset(v,,sizeof(v)); v[]=;
ll st=; int t=;
for (int i=; i<=m; i++)
{
if (v[b[i]]==-) v[b[i]]=++t;
b[i]=v[b[i]];
st<<=; st|=b[i];
}
st<<=; st|=b[m+];
return st;
} void shift()
{
for (int i=m;i; i--) b[i]=b[i-];
b[]=;
} void dp(int i,int j)
{
for (int k=; k<=h[p^].len; k++)
{
get(h[p^].st[k]);
if (!a[i][j])
{
b[j]=b[j-]=;
h[p].push(put(),h[p^].f[k]);
continue;
}
int x=b[j],y=b[j-];
if (b[m+])
{
if (!x&&!y&&a[i][j]!=)
{
b[j]=b[j-]=;
h[p].push(put(),h[p^].f[k]);
}
continue;
}
if (x&&y)
{
b[j]=b[j-]=;
if (x!=y){
for (int r=; r<=m; r++) if (b[r]==x) b[r]=y;
}
else b[m+]=;
h[p].push(put(),h[p^].f[k]);
}
else if ((x&&!y)||(!x&&y))
{
int r=x+y;
if (a[i][j+])
{
b[j]=r; b[j-]=;
h[p].push(put(),h[p^].f[k]);
}
if (a[i+][j])
{
b[j-]=r; b[j]=;
h[p].push(put(),h[p^].f[k]);
}
}
else {
if (a[i][j+]&&a[i+][j])
{
b[j]=b[j-]=m+;
h[p].push(put(),h[p^].f[k]);
}
if (a[i][j]==)
{
b[j]=b[j-]=;
h[p].push(put(),h[p^].f[k]);
}
}
}
} int main()
{
char s[]; int cas;
scanf("%d",&cas);
for (int tt=; tt<=cas; tt++)
{
scanf("%d%d",&n,&m);
memset(a,,sizeof(a));
for (int i=; i<=n; i++)
{
scanf("%s",s+);
for (int j=; j<=m; j++)
if (s[j]=='O') a[i][j]=;
else if (s[j]=='*') a[i][j]=;
}
h[].clr();
h[].push(,); p=;
for (int i=; i<=n; i++)
{
p^=; h[p].clr();
for (int k=; k<=h[p^].len; k++)
{
get(h[p^].st[k]); shift();
h[p].push(put(),h[p^].f[k]);
}
for (int j=; j<=m; j++)
{
p^=; h[p].clr();
dp(i,j);
}
}
ll ans=;
for (int i=; i<=h[p].len; i++)
ans+=h[p].f[i];
printf("Case %d: %I64d\n",tt,ans);
}
return ;
}
fzu1977
hdu3377
#include<iostream>
#include<cstdio>
#include<cstring>
typedef long long ll;
const int mo=;
const int maxl=;
const int inf=-;
using namespace std;
struct node{
int p[mo],nex[maxl],len,f[maxl];
ll st[maxl];
void clr()
{
len=; memset(p,,sizeof(p));
}
void push(ll nw,int s)
{
int x=nw%mo;
for (int i=p[x];i!=-; i=nex[i])
if (st[i]==nw)
{
f[i]=max(f[i],s);
return;
}
st[++len]=nw; f[len]=s;
nex[len]=p[x]; p[x]=len;
}
} h[];
int n,m,cas,p,ex,ey;
int a[][],b[],v[]; void get(ll st)
{
for (int i=m; i>=; i--)
{
b[i]=st&;
st>>=;
}
} ll put()
{
memset(v,,sizeof(v)); v[]=;
ll st=; int t=;
for (int i=; i<=m; i++)
{
if (v[b[i]]==-) v[b[i]]=++t;
b[i]=v[b[i]];
st<<=; st|=b[i];
}
return st;
} void shift()
{
for (int i=m;i; i--) b[i]=b[i-];
b[]=;
} void dp(int i,int j)
{
for (int k=; k<=h[-p].len; k++)
{
get(h[-p].st[k]);
int x=b[j],y=b[j-];
if (i==&&j==)
{
if (i<n) {b[j-]=m+; b[j]=; h[p].push(put(),h[-p].f[k]+a[i][j]);}
if (j<m) {b[j-]=; b[j]=m+; h[p].push(put(),h[-p].f[k]+a[i][j]);}
continue;
}
if (i==n&&j==m)
{
if ((!x&&y)||(!y&&x))
{
b[j]=b[j-]=;
h[p].push(put(),h[-p].f[k]+a[i][j]);
}
continue;
}
if (x&&y)
{
if (x!=y)
{
b[j]=b[j-]=;
if (x!=y)
for (int r=; r<=m; r++) if (b[r]==x) b[r]=y;
if (j==m) shift();
h[p].push(put(),h[-p].f[k]+a[i][j]);
}
}
else if ((x&&!y)||(!x&&y))
{
int r=x+y;
if (j<m) {
b[j]=r; b[j-]=;
h[p].push(put(),h[-p].f[k]+a[i][j]);
}
if (i<n)
{
b[j-]=r; b[j]=;
if (j==m) shift();
h[p].push(put(),h[-p].f[k]+a[i][j]);
}
}
else {
if (i<n&&j<m)
{
b[j]=b[j-]=m+;
h[p].push(put(),h[-p].f[k]+a[i][j]);
}
b[j]=b[j-]=;
if (j==m) shift();
h[p].push(put(),h[-p].f[k]);
}
}
} int main()
{
int tt=;
while (scanf("%d%d",&n,&m)!=EOF)
{
for (int i=; i<=n; i++)
for (int j=; j<=m; j++)
scanf("%d",&a[i][j]);
if (n==&&m==)
{
printf("Case %d: %d\n",++tt,a[][]);
continue;
}
h[].clr();
h[].push(,); p=;
for (int i=; i<=n; i++)
for (int j=; j<=m; j++)
{
p^=; h[p].clr();
dp(i,j);
}
int ans=inf;
for (int i=; i<=h[p].len; i++)
ans=max(ans,h[p].f[i]);
printf("Case %d: %d\n",++tt,ans);
}
return ;
}
hdu3377
poj3133
#include<iostream>
#include<cstdio>
#include<cstring> const int maxl=;
using namespace std;
struct node{
int len,f[maxl],st[maxl];
void clr()
{
for (int i=; i<=len; i++) f[st[i]]=-;
len=;
}
void push(int nw,int s)
{
if (f[nw]==-)
{
st[++len]=nw;
f[nw]=s;
}
else f[nw]=min(f[nw],s);
}
} h[];
int n,m,cas,p;
int a[][],b[]; void get(int st)
{
for (int i=m; i>=; i--)
{
b[i]=st&;
st>>=;
}
} int put()
{
int st=;
for (int i=; i<=m; i++) {st<<=; st|=b[i];}
return st;
} void shift()
{
for (int i=m;i; i--) b[i]=b[i-];
b[]=;
} void dp(int i,int j)
{
for (int k=; k<=h[-p].len; k++)
{
get(h[-p].st[k]);
int x=b[j],y=b[j-],st=h[-p].st[k];
if (a[i][j]!=)
{
if (!a[i][j]&&!x&&!y) h[p].push(st,h[-p].f[st]);
else if (a[i][j]>)
{
if (((x&&!y)||(!x&&y))&&(x+y==a[i][j])) {b[j]=b[j-]=; h[p].push(put(),h[-p].f[st]+);}
else if (!x&&!y)
{
if (a[i][j+]==a[i][j]||a[i][j+]==) {b[j]=a[i][j]; b[j-]=; h[p].push(put(),h[-p].f[st]+);}
if (a[i+][j]==a[i][j]||a[i+][j]==) {b[j-]=a[i][j]; b[j]=; h[p].push(put(),h[-p].f[st]+);}
}
}
continue;
}
if (x&&y&&x==y) {b[j]=b[j-]=; h[p].push(put(),h[-p].f[st]+);}
else if ((x&&!y)||(!x&&y))
{
int r=x+y;
if (a[i][j+]==||a[i][j+]==r) {b[j]=r; b[j-]=; h[p].push(put(),h[-p].f[st]+);}
if (a[i+][j]==||a[i+][j]==r) {b[j-]=r; b[j]=; h[p].push(put(),h[-p].f[st]+);}
}
else if (!x&&!y)
{
if (a[i][j+]&&a[i+][j])
{
if (a[i][j+]==&&a[i+][j]==)
{
b[j]=b[j-]=; h[p].push(put(),h[-p].f[st]+);
b[j]=b[j-]=; h[p].push(put(),h[-p].f[st]+);
}
else if (a[i][j+]==&&a[i+][j]==||a[i][j+]==&&a[i+][j]==||a[i+][j]==&&a[i][j+]==) {b[j]=b[j-]=; h[p].push(put(),h[-p].f[st]+);}
else if (a[i][j+]==&&a[i+][j]==||a[i][j+]==&&a[i+][j]==||a[i+][j]==&&a[i][j+]==) {b[j]=b[j-]=; h[p].push(put(),h[-p].f[st]+);}
}
h[p].push(st,h[-p].f[st]);
}
}
} int main()
{
h[].len=h[].len=;
memset(h[].f,,sizeof(h[].f));
memset(h[].f,,sizeof(h[].f));
scanf("%d%d",&n,&m);
while (n&&m)
{
memset(a,,sizeof(a));
for (int i=; i<=n; i++)
{
for (int j=; j<=m; j++)
{
scanf("%d",&a[i][j]);
if (a[i][j]==||a[i][j]==) a[i][j]^=;
}
}
h[].push(,); p=;
for (int i=; i<=n; i++)
{
p^=; h[p].clr();
for (int k=; k<=h[-p].len; k++)
{
get(h[-p].st[k]); int st=h[-p].st[k]; shift();
h[p].push(put(),h[-p].f[st]);
}
for (int j=; j<=m; j++)
{
p^=; h[p].clr();
dp(i,j);
}
}
int ans=;
for (int i=; i<=h[p].len; i++)
{
int st=h[p].st[i];
ans+=h[p].f[st];
}
if (ans>) ans-=;
printf("%d\n",ans);
h[].clr(); h[].clr();
scanf("%d%d",&n,&m);
}
return ;
}
poj3133
hdu4285
#include<iostream>
#include<cstdio>
#include<cstring>
typedef long long ll;
const int ha=;
const int maxl=;
const int mo=;
using namespace std;
struct node{
int p[ha],nex[maxl],len,f[maxl];
ll st[maxl];
void clr()
{
len=; memset(p,,sizeof(p));
}
void push(ll nw,int s)
{
int x=nw%ha;
for (int i=p[x];i!=-; i=nex[i])
if (st[i]==nw)
{
f[i]=(f[i]+s)%mo;
return;
}
st[++len]=nw; f[len]=s;
nex[len]=p[x]; p[x]=len;
}
} h[];
int n,m,cas,p,t;
int a[][],b[],v[]; void get(ll st)
{
b[m+]=st&; st>>=;
for (int i=m; i>=; i--)
{
b[i]=st&;
st>>=;
}
} ll put()
{
memset(v,,sizeof(v)); v[]=;
ll st=; int t=;
for (int i=; i<=m; i++)
{
if (v[b[i]]==-) v[b[i]]=++t;
b[i]=v[b[i]];
st<<=; st|=b[i];
}
st<<=; st|=b[m+];
return st;
} void shift()
{
for (int i=m;i; i--) b[i]=b[i-];
b[]=;
} bool check(int j)
{
bool ff=;
for (int i=; i<j-; i++)
if (b[i]) ff^=;
if (!ff) return ;
for (int i=j+; i<=m; i++)
if (b[i]) ff^=;
return ff;
} void dp(int i,int j)
{
for (int k=; k<=h[p^].len; k++)
{
get(h[p^].st[k]);
if (!a[i][j])
{
b[j]=b[j-]=;
h[p].push(put(),h[p^].f[k]);
continue;
}
int x=b[j],y=b[j-];
if (b[m+]==t) continue;
if (x&&y)
{
b[j]=b[j-]=;
if (x!=y){
for (int r=; r<=m; r++) if (b[r]==x) b[r]=y;
}
else {
if (check(j)) ++b[m+]; else continue;
}
h[p].push(put(),h[p^].f[k]);
}
else if ((x&&!y)||(!x&&y))
{
int r=x+y;
if (a[i][j+])
{
b[j]=r; b[j-]=;
h[p].push(put(),h[p^].f[k]);
}
if (a[i+][j])
{
b[j-]=r; b[j]=;
h[p].push(put(),h[p^].f[k]);
}
}
else {
if (a[i][j+]&&a[i+][j])
{
b[j]=b[j-]=m+;
h[p].push(put(),h[p^].f[k]);
}
}
}
} int main()
{
char s[]; int cas;
scanf("%d",&cas);
while (cas--)
{
scanf("%d%d%d",&n,&m,&t);
memset(a,,sizeof(a));
for (int i=; i<=n; i++)
{
scanf("%s",s+);
for (int j=; j<=m; j++)
if (s[j]=='.') a[i][j]=;
}
h[].clr();
h[].push(,); p=;
for (int i=; i<=n; i++)
{
p^=; h[p].clr();
for (int k=; k<=h[p^].len; k++)
{
get(h[p^].st[k]); shift();
h[p].push(put(),h[p^].f[k]);
}
for (int j=; j<=m; j++)
{
p^=; h[p].clr();
dp(i,j);
}
}
int ans=;
for (int i=; i<=h[p].len; i++)
{
get(h[p].st[i]);
if (b[m+]==t) ans=(ans+h[p].f[i])%mo;
}
printf("%d\n",ans);
}
return ;
}
hdu4285
矩阵乘法加速插头dp的几题一直想做,抽时间要补一下
初探插头dp的更多相关文章
- 初探 插头DP
因为这题,气得我火冒三丈! 这数据是不是有问题啊!我用cin代替scanf后居然就AC了(本来一直卡在Test 18)!导致我调(对)试(排)了一个小时!! UPD:后来细细想想,会不会是因为scan ...
- [专题总结]初探插头dp
彻彻底底写到自闭的一个专题. 就是大型分类讨论,压行+宏定义很有优势. 常用滚动数组+哈希表+位运算.当然还有轮廓线. Formula 1: 经过所有格子的哈密顿回路数. 每个非障碍点必须有且仅有2个 ...
- 插头dp初探
问题描述 插头dp用于解决一类可基于图连通性递推的问题.用插头来表示轮廓线上的连通性,然后根据连通性与下一位结合讨论进行转移. 表示连通性的方法 与字符串循环最小表示不同,这种方法用于给轮廓线上的联通 ...
- 插头dp
插头dp 感受: 我觉得重点是理解,算法并不是直接想出怎样由一种方案变成另一种方案.而是方案本来就在那里,我们只是枚举状态统计了答案. 看看cdq的讲义什么的,一开始可能觉得状态很多,但其实灰常简单 ...
- HDU 4113 Construct the Great Wall(插头dp)
好久没做插头dp的样子,一开始以为这题是插头,状压,插头,状压,插头,状压,插头,状压,无限对又错. 昨天看到的这题. 百度之后发现没有人发题解,hust也没,hdu也没discuss...在acm- ...
- HDU 4949 Light(插头dp、位运算)
比赛的时候没看题,赛后看题觉得比赛看到应该可以敲的,敲了之后发现还真就会卡题.. 因为写完之后,无限TLE... 直到后来用位运算代替了我插头dp常用的decode.encode.shift三个函数以 ...
- 插头DP专题
建议入门的人先看cd琦的<基于连通性状态压缩的动态规划问题>.事半功倍. 插头DP其实是比较久以前听说的一个东西,当初是水了几道水题,最近打算温习一下,顺便看下能否入门之类. 插头DP建议 ...
- HDU 1693 Eat the Trees(插头DP、棋盘哈密顿回路数)+ URAL 1519 Formula 1(插头DP、棋盘哈密顿单回路数)
插头DP基础题的样子...输入N,M<=11,以及N*M的01矩阵,0(1)表示有(无)障碍物.输出哈密顿回路(可以多回路)方案数... 看了个ppt,画了下图...感觉还是挺有效的... 参考 ...
- HDU 1693 Eat the Trees(插头DP)
题目链接 USACO 第6章,第一题是一个插头DP,无奈啊.从头看起,看了好久的陈丹琦的论文,表示木看懂... 大体知道思路之后,还是无法实现代码.. 此题是插头DP最最简单的一个,在一个n*m的棋盘 ...
随机推荐
- springmvc文件上传,出现400 的错误问题
遇见的原因是公司系统上的图片上传忽然不好使了,报错400.单独针对这个模块调了好长时间都没解决,后来才发现前几天做过一个excel上传导入的功能... 使用SptingMVC3.1.3 对于文件上传提 ...
- feof问题
feof()函数是我们C语言中操作文件常见的函数,也是我们最容易出错的函数 这个函数用来表示文件指针是否已经到了文件末尾的下一个位置.这个函数是通用的 可以用在文本文件和二进制文件 (EOF是文件结束 ...
- [剑指Offer] 15.反转链表
题目描述 输入一个链表,反转链表后,输出链表的所有元素. [思路1]三个指针在链表上同时滑动. /* struct ListNode { int val; struct ListNode *next; ...
- BZOJ4597 SHOI2016随机序列(线段树)
先考虑题目所说的太简单了的问题.注意到只要把加减号相取反,就可以得到一对除了第一项都互相抵消的式子.于是得到答案即为Σf(i)g(i),其中f(i)为前缀积,g(i)为第i个数前面所有符号均填乘号,第 ...
- Java Web开发之路(一)——环境配置
1. 下载JDK(Java Development Kit)工具包.其中包括运行Java程序所必须的JRE环境及开发过程中常用的库文件. (JDK与JRE的关系: JDK是Java的开发环境,在编写J ...
- springboot 实现自定义注解
1.定义一个注解@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface T ...
- ng的ngModel用来处理表单操作
https://segmentfault.com/a/1190000009126012
- Java 中request.getInputStream()和BufferedReader 和 InputStreamReader 用法
关于request.getInputStream(): http://www.cnblogs.com/steve-cnblogs/articles/5420198.html 浏览器 采用了一种编码方式 ...
- LVM to increase and reduce 10G size for /data
=======================increase10G for/data=============================(system env /dev/MongoData00 ...
- 自定义orderBy字母函数
orderedUsers: function () { var arr = this.users; for (var i = 0; i < arr.length - 1; i++) { for ...