ZOJ 3466 The Hive II

  插头DP。。

  求用若干个回路走遍整张图的方案数。。然而格子是六边形的TAT

  想了好久...按照列来转移好写一点。。其实和正方形格子差不多?

  膜了标程才知道,如果回路数没有限制的话。。可以只记录有没有插头,而不用去记录插头属于哪个联通块。。

  (要是去记录插头属于哪个联通块就会爆long long了TAT

  代码依然很慢。。。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<algorithm>
  5 #define ll long long
  6 using namespace std;
  7 const int maxzt=1023333,modd=6023,inf=1002333333;
  8 struct zs1{
  9     struct zs{
 10         int too,pre;
 11     }e[maxzt];int tot,last[modd];
 12     int zt[maxzt];
 13     ll f[maxzt];
 14     inline int get(int v){
 15         int i,x=v%modd;
 16         for(i=last[x];i&&e[i].too!=v;i=e[i].pre);
 17         if(i)return i;
 18         e[++tot].too=v,e[tot].pre=last[x],last[x]=tot;
 19         f[tot]=0,zt[tot]=v;
 20         return tot;
 21     }
 22 }hm[2];
 23 bool can[13][13];
 24 int mp[21];
 25 int i,j,k,n,m,ans;
 26
 27 inline void upd(int &a,int b){if(b<a)a=b;}
 28
 29 inline int encode(){
 30     int x=0;
 31     for(int i=0;i<n<<1;i++)x=x<<1|mp[i];return x;
 32 }
 33 inline void decode(int x){
 34     for(int i=n*2-1;i>=0;i--)mp[i]=x&1,x>>=1;
 35 }
 36 inline void clr(bool now){
 37     memset(hm[now].last,0,modd<<2);
 38     hm[now].tot=0;
 39 }
 40 inline void dp_blank(int x,int y,bool pre){
 41     int up,zx,zs,i,zt;ll f;bool now=pre^1;int posup,poszs,poszx,ys,yx;
 42     if(y&1)ys=x;else ys=x-1;yx=ys+1;
 43     clr(now);//printf("    %d,%d\n",x,y);
 44     for(i=1;i<=hm[pre].tot;i++){
 45         zt=hm[pre].zt[i],f=hm[pre].f[i];
 46         if(x==1)zt>>=1;
 47         decode(zt);
 48 //        for(int j=0;j<n<<1;j++)printf(" %d",mp[j]);printf("   %lld\n",f);
 49         if(y&1)posup=(x<<1)-2,poszs=(x<<1)-1,poszx=x<<1;
 50             else posup=max(0,(x<<1)-3),poszs=(x<<1)-2,poszx=(x<<1)-1;
 51         up=mp[posup],zs=mp[poszs],zx=mp[poszx];
 52 //        printf("   %d %d %d     %d %d %d\n",up,zs,zx,posup,poszs,poszx);
 53         if(up+zs+zx==0){
 54             if(can[x+1][y]&&can[ys][y+1])
 55                 mp[poszs]=0,mp[poszx]=mp[posup]=1,
 56                 hm[now].f[ hm[now].get(encode()) ]+=f;
 57             if(can[x+1][y]&&can[yx][y+1])
 58                 mp[posup]=0,mp[poszx]=mp[poszs]=1,
 59                 hm[now].f[ hm[now].get(encode()) ]+=f;
 60             if(can[ys][y+1]&&can[yx][y+1])
 61                 mp[poszx]=0,mp[posup]=mp[poszs]=1,
 62                 hm[now].f[ hm[now].get(encode()) ]+=f;
 63         }
 64         if(up+zs+zx==1){
 65             if(can[x+1][y])
 66                 mp[poszs]=mp[posup]=0,mp[poszx]=1,
 67                 hm[now].f[ hm[now].get(encode()) ]+=f;
 68             if(can[ys][y+1])
 69                 mp[poszs]=mp[poszx]=0,mp[posup]=1,
 70                 hm[now].f[ hm[now].get(encode()) ]+=f;
 71             if(can[yx][y+1])//puts("yx"),
 72                 mp[posup]=mp[poszx]=0,mp[poszs]=1,
 73                 hm[now].f[ hm[now].get(encode()) ]+=f;
 74         }
 75         if(up+zs+zx==2)
 76             mp[poszx]=mp[poszs]=mp[posup]=0,
 77             hm[now].f[ hm[now].get(encode()) ]+=f;
 78     }
 79 }
 80 inline void dp_bar(int x,int y,bool pre){
 81     int i,up,zs,zx,zt;ll f;bool now=pre^1;int posup,poszs,poszx;
 82
 83     clr(now);//printf("   # %d,%d\n",x,y);
 84     for(i=1;i<=hm[pre].tot;i++){
 85         zt=hm[pre].zt[i],f=hm[pre].f[i];
 86         if(x==1)zt>>=1;
 87         decode(zt);
 88 //        for(int j=0;j<n<<1;j++)printf(" %d",mp[j]);printf("    %lld\n",f);
 89         if(y&1)posup=(x<<1)-2,poszs=(x<<1)-1,poszx=x<<1;
 90             else posup=max(0,(x<<1)-3),poszs=(x<<1)-2,poszx=(x<<1)-1;
 91         up=mp[posup],zs=mp[poszs],zx=mp[poszx];
 92         if(up+zs+zx==0)
 93             hm[now].f[ hm[now].get(encode()) ]+=f;
 94     }
 95 }
 96 char s[23];
 97 int main(){
 98     while(scanf("%d",&n)!=EOF){
 99         scanf("%d",&m);
100         memset(can,0,sizeof(can));
101         for(i=1;i<=n;i++)for(j=1;j<=8;j++)can[i][j]=1;
102         for(i=1;i<=m;i++)scanf("%s",s),can[s[0]-‘A‘+1][s[1]-‘A‘+1]=0;
103
104         bool now=1,pre=0;
105         clr(pre),hm[pre].f[ hm[pre].get(0) ]=1;
106         for(j=1;j<=8;j++)for(i=1;i<=n;swap(now,pre),i++)
107             if(can[i][j])dp_blank(i,j,pre);else dp_bar(i,j,pre);
108         ll ans=0;
109         for(i=1;i<=hm[pre].tot;i++)ans+=hm[pre].f[i];
110         printf("%lld\n",ans);
111     }
112     return 0;
113 }

发现取模的数字会对效率有很大影响。。。。平时似乎不会啊= =

模数取10w出头就好了。。

时间: 2024-08-10 23:14:20

ZOJ 3466 The Hive II的相关文章

ZOJ 3466 The Hive II (插头DP,变形)

题意:有一个n*8的蜂房(6边形的格子),其中部分是障碍格子,其他是有蜂蜜的格子,每次必须走1个圈取走其中的蜂蜜,在每个格子只走1次,且所有蜂蜜必须取走,有多少种取法? 思路: 以前涉及的只是n*m的矩阵,也就是四边形的,现在变成了6边形,那么每个格子也就有6个方向可以出/进.为了方便考虑,将蜂房变成按列来扫,那么轮廓线需要2*n+1个插头信息.这里不需要用到括号表示法或者最小表示法,只需要表示该位置是否有线即可,所以每个插头仅需1个位就可以表示了. 转置一下后的蜂房应该是这样的: 轮廓线是一个

zoj 3332 Strange Country II

转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3332 Description You want to visit a strange country. There are n cities in the country. Cities are numbered from 1 to n. The unique way to trav

zoj 3620 Escape Time II

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4744 Escape Time II Time Limit: 2 Seconds      Memory Limit: 65536 KB There is a fire in LTR ’ s home again. The fire can destroy all the things in t seconds, so LTR has to escape in t second

zoj 3620 Escape Time II dfs

Escape Time II Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3620 Description There is a fire in LTR ’ s home again. The fire can destroy all the things in t seconds, so LTR has to escape i

ZOJ 3557-How Many Sets II(Lucas定理+插板法求组合数)

题目地址:ZOJ 3557 题意:给一个集合,一共n个元素,从中选取m个元素,满足选出的元素中没有相邻的元素,一共有多少种选法(结果对p取模1 <= p <= 10^9) 思路:用插板法求出组合数.既然是从n个数中选择m个数,那么剩下的数为n-m,那么可以产生n-m+1个空,这道题就变成了把m个数插到这n-m+1个空中有多少种方法,即C(n-m+1,m)%p.然后就Lucas定理上去乱搞.因为这道题的p较大,所以不能预处理. #include <stdio.h> #include

ZOJ 3574 Under Attack II 归并排序求逆序对

Under Attack II Time Limit: 5 Seconds      Memory Limit: 65536 KB Because of the sucessfully calculation in Under Attack I, Doctor is awarded with Courage Cross and promoted to lieutenant. But the war seems to end in never, now Doctor has a new order

ZOJ 3627 Treasure Hunt II (贪心,模拟)

题意:有n个城市并排着,每个城市有些珠宝,有两个人站在第s个城市准备收集珠宝,两人可以各自行动,但两人之间的距离不能超过dis,而且每经过一个城市就需要消耗1天,他们仅有t天时间收集珠宝,问最多能收集多少珠宝? 思路: 其实就是类似一个滑动窗口在收集一个序列上的权值.首先两个人可以同时往两边散开,直到极限距离dis(这样省时),然后他们可能往左/右走,也可能往左走一会儿再往右走,也可能往右走一会儿再往左走.可以看出其实这些考虑都是对称的,那么我们主要考虑1边就行了.可以尝试枚举往左边走k天,其他

ZOJ 3042 City Selection II 【序】【离散化】【数学】

题意: 输入数据n,m.n代表工厂的数量,m代表城市的数量. 接下来n+m行为工厂和城市的坐标. 规定如图所示方向刮风,工厂的air会污染风向地区的air. 注意,工厂和城市的坐标表示的是从x到x+1从y到y+1之间小正方形都是工厂区域,规定如果只有一个coner的air被污染那么该地区视为无污染. 要求输出有多少不被污染的城市. 坑: 思考了很多问题.... 1.加入某城市的正下方是工厂怎么办...这个是否算污染. 2.假如有两个角被污染了怎么办...算污染吗. 坑了一整天.没办法找大神的代码

ZOJ 3332 Strange Country II (竞赛图构造哈密顿通路)

链接:http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=3332 题意: 给你一个N,代表含有N个点的竞赛图,接着的N * (N- 1) / 2行两个点u, v,代表存在有向边<u,v>,问是否能构造出来一个哈密顿通路. 思路: 竞赛图一定含有哈密顿通路,不一定含有哈密顿回路.则不可能出现不存在的情况,直接构造就可以,至于方法可看我的另外一篇文章:http://www.cnblogs.com/Ash-ly/p/5452580.