初探插头dp

Posted phile的空间

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初探插头dp相关的知识,希望对你有一定的参考价值。

开学那个月学了点新东西,不知道还记不记得了,mark一下

感觉cdq的论文讲的很详细

题主要跟着kuangbin巨做了几道基础的

http://www.cnblogs.com/kuangbin/archive/2012/10/02/2710343.html

还有几道没做,留着坑

感觉广义括号表示法虽然神奇,但一般最小表示法就够用了吧,感觉最小表示法更直观一点

hdu1693

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 typedef long long ll;
 5 using namespace std;
 6 ll f[13][13][1<<13];
 7 int a[13][13];
 8 int n,m,cas;
 9 
10 int main()
11 {
12   scanf("%d",&cas);
13   for (int tt=1; tt<=cas; tt++)
14   {
15     scanf("%d%d",&n,&m);
16     for (int i=1; i<=n; i++)
17       for (int j=1; j<=m; j++)
18         scanf("%d",&a[i][j]);
19     printf("Case %d: ",tt);
20     memset(f,0,sizeof(f));
21     f[0][m][0]=1;
22     for (int i=1; i<=n; i++)
23     {
24       for (int j=0; j<(1<<m); j++)
25         f[i][0][j<<1]=f[i-1][m][j];
26       for (int j=1; j<=m; j++)
27       {
28         for (int st=0; st<(1<<(m+1)); st++)
29         {
30           int x=1<<j,y=1<<(j-1);
31           if (a[i][j])
32           {
33             if ((st&x)&&(st&y)) f[i][j][st]=f[i][j-1][st^x^y];
34             else if (!(st&x)&&!(st&y)) f[i][j][st]=f[i][j-1][st|x|y];
35             else f[i][j][st]=f[i][j-1][st]+f[i][j-1][st^x^y];
36           }
37           else {
38             if (!(st&x)&&!(st&y)) f[i][j][st]=f[i][j-1][st];
39             else f[i][j][st]=0;
40           }
41         }
42       }
43     }
44     printf("There are %lld ways to eat the trees.\\n",f[n][m][0]);
45   }
46   return 0;
47 }
hdu1693

poj1793(男人八题!)

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 typedef long long ll;
  5 const int mo=30007;
  6 const int maxl=1000010;
  7 using namespace std;
  8 struct node{
  9   int p[mo],nex[maxl],len;
 10   ll st[maxl],f[maxl];
 11   void clr()
 12   {
 13     len=0; memset(p,255,sizeof(p));
 14   }
 15   void push(ll nw,ll s)
 16   {
 17     int x=nw%mo;
 18     for (int i=p[x];i!=-1; i=nex[i])
 19       if (st[i]==nw)
 20       {
 21         f[i]+=s;
 22         return;
 23       }
 24     st[++len]=nw; f[len]=s;
 25     nex[len]=p[x]; p[x]=len;
 26   }
 27 } h[2];
 28 int n,m,cas,p,ex,ey;
 29 int a[15][15],b[15],v[15];
 30 
 31 void get(ll st)
 32 {
 33   for (int i=m; i>=0; i--)
 34   {
 35     b[i]=st&7;
 36     st>>=3;
 37   }
 38 }
 39 
 40 ll put()
 41 {
 42   memset(v,255,sizeof(v)); v[0]=0;
 43   ll st=0; int t=0;
 44   for (int i=0; i<=m; i++)
 45   {
 46     if (v[b[i]]==-1) v[b[i]]=++t;
 47     b[i]=v[b[i]];
 48     st<<=3; st|=b[i];
 49   }
 50   return st;
 51 }
 52 
 53 void shift()
 54 {
 55   for (int i=m;i; i--) b[i]=b[i-1];
 56   b[0]=0;
 57 }
 58 
 59 void work(int j,int k)
 60 {
 61   if (j==m) shift();
 62   h[p].push(put(),h[1-p].f[k]);
 63 }
 64 
 65 void dp(int i,int j)
 66 {
 67   for (int k=1; k<=h[1-p].len; k++)
 68   {
 69     get(h[1-p].st[k]);
 70     if (!a[i][j])
 71     {
 72       b[j]=b[j-1]=0; work(j,k);
 73       continue;
 74     }
 75     int x=b[j],y=b[j-1];
 76     if (x&&y)
 77     {
 78       if ((x==y&&i==ex&&j==ey)||(x!=y))
 79       {
 80         b[j]=b[j-1]=0;
 81         if (x!=y)
 82           for (int r=0; r<=m; r++) if (b[r]==x) b[r]=y;
 83         work(j,k);
 84       }
 85     }
 86     else if ((x&&!y)||(!x&&y))
 87     {
 88       int r=x+y;
 89       if (a[i][j+1]) {b[j]=r; b[j-1]=0; work(j,k);}
 90       if (a[i+1][j]) {b[j-1]=r; b[j]=0; work(j,k);}
 91     }
 92     else if (a[i][j+1]&&a[i+1][j])
 93     {
 94       b[j]=b[j-1]=m+1;
 95       work(j,k);
 96     }
 97   }
 98 }
 99 
100 int main()
101 {
102   char s[12];
103   scanf("%d%d",&n,&m);
104   while (n&&m)
105   {
106     memset(a,0,sizeof(a));
107     for (int i=1; i<=n; i++)
108     {
109       scanf("%s",s+1);
110       for (int j=1; j<=m; j++)
111         if (s[j]==\'.\') a[i][j]=1;
112     }
113     for (int i=1; i<=m; i++)
114     {
115       a[n+2][i]=1;
116       a[n+1][i]=(i>1&&i<m)?0:1;
117     }
118     n+=2;  ex=n; ey=m;
119     h[0].clr();
120     h[0].push(0,1);  p=0;
121     for (int i=1; i<=n; i++)
122       for (int j=1; j<=m; j++)
123       {
124         p^=1; h[p].clr();
125         dp(i,j);
126       }
127     ll ans=0;
128     for (int i=1; i<=h[p].len; i++)
129       ans+=h[p].f[i];
130     printf("%lld\\n",ans);
131     scanf("%d%d",&n,&m);
132   }
133   return 0;
134 }
poj1793

fzu1977

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 typedef long long ll;
  5 const int mo=30007;
  6 const int maxl=300010;
  7 using namespace std;
  8 struct node{
  9   int p[mo],nex[maxl],len;
 10   ll st[maxl],f[maxl];
 11   void clr()
 12   {
 13     len=0; memset(p,255,sizeof(p));
 14   }
 15   void push(ll nw,ll s)
 16   {
 17     int x=nw%mo;
 18     for (int i=p[x];i!=-1; i=nex[i])
 19       if (st[i]==nw)
 20       {
 21         f[i]+=s;
 22         return;
 23       }
 24     st[++len]=nw; f[len]=s;
 25     nex[len]=p[x]; p[x]=len;
 26   }
 27 } h[2];
 28 int n,m,cas,p,ex,ey;
 29 int a[15][15],b[15],v[15];
 30 
 31 void get(ll st)
 32 {
 33   b[m+1]=st&1; st>>=1;
 34   for (int i=m; i>=0; i--)
 35   {
 36     b[i]=st&7;
 37     st>>=3;
 38   }
 39 }
 40 
 41 ll put()
 42 {
 43   memset(v,255,sizeof(v)); v[0]=0;
 44   ll st=0; int t=0;
 45   for (int i=0; i<=m; i++)
 46   {
 47     if (v[b[i]]==-1) v[b[i]]=++t;
 48     b[i]=v[b[i]];
 49     st<<=3; st|=b[i];
 50   }
 51   st<<=1; st|=b[m+1];
 52   return st;
 53 }
 54 
 55 void shift()
 56 {
 57   for (int i=m;i; i--) b[i]=b[i-1];
 58   b[0]=0;
 59 }
 60 
 61 void dp(int i,int j)
 62 {
 63   for (int k=1; k<=h[p^1].len; k++)
 64   {
 65     get(h[p^1].st[k]);
 66     if (!a[i][j])
 67     {
 68       b[j]=b[j-1]=0;
 69       h[p].push(put(),h[p^1].f[k]);
 70       continue;
 71     }
 72     int x=b[j],y=b[j-1];
 73     if (b[m+1])
 74     {
 75       if (!x&&!y&&a[i][j]!=1)
 76       {
 77         b[j]=b[j-1]=0;
 78         h[p].push(put(),h[p^1].f[k]);
 79       }
 80       continue;
 81     }
 82     if (x&&y)
 83     {
 84       b[j]=b[j-1]=0;
 85       if (x!=y){
 86         for (int r=0; r<=m; r++) if (b[r]==x) b[r]=y;
 87       }
 88       else b[m+1]=1;
 89       h[p].push(put(),h[p^1].f[k]);
 90     }
 91     else if ((x&&!y)||(!x&&y))
 92     {
 93       int r=x+y;
 94       if (a[i][j+1])
 95       {
 96         b[j]=r; b[j-1]=0;
 97         h[p].push(put(),h[p^1].f[k]);
 98       }
 99       if (a[i+1][j])
100       {
101         b[j-1]=r; b[j]=0;
102         h[p].push(put(),h[p^1].f[k]);
103       }
104     }
105     else {
106       if (a[i][j+1]&&a[i+1][j])
107       {
108         b[j]=b[j-1]=m+1;
109         h[p].push(put(),h[p^1].f[k]);
110       }
111       if (a[i][j]==2)
112       {
113         b[j]=b[j-1]=0;
114         h[p].push(put(),h[p^1].f[k]);
115       }
116     }
117   }
118 }
119 
120 int main()
121 {
122   char s[15]; int cas;
123   scanf("%d",&cas);
124   for (int tt=1; tt<=cas; tt++)
125   {
126     scanf("%d%d",&n,&m);
127     memset(a,0,sizeof(a));
128     for (int i=1; i<=n; i++)
129     {
130       scanf("%s",s+1);
131       for (int j=1; j<=m; j++)
132         if (s[j]==\'O\') a[i][j]=1;
133         else if (s[j]==\'*\') a[i][j]=2;
134     }
135     h[0].clr();
136     h[0].push(0,1);  p=0;
137     for (int i=1; i<=n; i++)
138     {
139       p^=1; h[p].clr();
140       for (int k=1; k<=h[p^1].len; k++)
141       {
142         get(h[p^1].st[k]); shift();
143         h[p].push(put(),h[p^1].f[k]);
144       }
145       for (int j=1; j<=m; j++)
146       {
147         p^=1; h[p].clr();
148         dp(i,j);
149       }
150     }
151     ll ans=0;
152     for (int i=1; i<=h[p].len; i++)
153       ans+=h[p].f[i];
154     printf("Case %d: %I64d\\n",tt,ans);
155   }
156   return 0;
157 }
fzu1977

hdu3377

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 typedef long long ll;
  5 const int mo=30007;
  6 const int maxl=1000010;
  7 const int inf=-100000007;
  8 using namespace std;
  9 struct node{
 10   int p[mo],nex[maxl],len,f[maxl];
 11   ll st[maxl];
 12   void clr()
 13   {
 14     len=0; memset(p,255,sizeof(p));
 15   }
 16   void push(ll nw,int s)
 17   {
 18     int x=nw%mo;
 19     for (int i=p[x];i!=-1; i=nex[i])
 20       if (st[i]==nw)
 21       {
 22         f[i]=max(f[i],s);
 23         return

以上是关于初探插头dp的主要内容,如果未能解决你的问题,请参考以下文章

插头DP入门

HDU4084 插头dp

插头dp

无聊的 邮递员 插头dp

HDU 1693 Eat the Trees (插头DP)

P5056 模板插头dp