【caioj】1489: 基于连通性状态压缩的动态规划问题:Formula 1 Ural1519
来源:互联网 发布:做淘宝后感想 编辑:程序博客网 时间:2024/05/22 01:41
今天在TYB大佬的带领下学了一发新姿势啊!!
感觉几年前的省选考过插头DP,就有一点点想学了。。
但是好像以前研究过一小阵子。。
由于没看懂就放弃了。。
然后这次跟着TYB大佬又来了一发。。
感觉还好
感觉这个算法的核心思想就是不断地分类讨论。。
要注意的地方很多。。
然后想学的人还是先看看论文,弄清楚点概念什么的
至于分类讨论,看代码就好
下面是我的代码,有“详细”的注释
哦,还有,学这个东西的时候一定要有纸和笔。。没看懂的地方一定要画。。不要相信什么人脑是无敌的
#include<cstdio>#include<cstring>#define ADD add(st,sum)typedef long long LL;const int MOD=100037;const int N=15;bool map[N][N];//是不是可以走 int n,m;int xx=-1,yy;//我们要寻找一个最下 最右的点——>当到他的时候就可以累计答案了LL ans=0;//答案个数LL a[2][MOD];//这种状态的数目,其实差不多是来辅助下面的数组 int b[2][MOD];//状态int num[2];//状态个数int HASH[MOD];/*0:无插头状态1:左括号插头2:右括号插头*/int get (int x,int p)//第j位 当然是四进制里面的第j位啦 {return (x>>(p-1)*2)&3;}int now=0;void add (int st,LL sum)//给当前的决策状态加上这个状态{ int ss=st%MOD; while (HASH[ss]!=-1&&b[now][HASH[ss]]!=st) { ss++;ss%=MOD; if (ss==0) ss=1; } if (HASH[ss]==-1) { HASH[ss]=++num[now]; b[now][num[now]]=st; a[now][num[now]]=sum; } else a[now][HASH[ss]]+=sum;}void change (int &s,int p,int v)//把s的第p位改为v{ s=s^(get(s,p)<<(p-1)*2); s=s^(v<<(p-1)*2);}void solve (){ a[0][1]=1;num[0]=1;b[0][1]=0; for (int u=1;u<=n;u++) { for (int i=1;i<=m;i++)//当前的转移节点,我们要尝试吧这个节点转到下一个 { now^=1; num[now]=0; memset(HASH,-1,sizeof(HASH)); for (int k=1;k<=num[now^1];k++)//继承上一个轮廓线的状态 { int st=b[now^1][k]; LL sum=a[now^1][k]; int p=get(st,i);//获得“竖着的”那个插头状态 int q=get(st,i+1);//获得“横着的”那个插头状态 // printf("%d %d %d %d %d %d\n",u,i,k,st,p,q); if (map[u][i]==false)//这个是障碍点 { if (p+q==0) ADD;//要是可以把它绕开就好了 continue; } if (p+q==0)//没有连到当前格子 { if (map[u][i+1]&&map[u+1][i]) { change(st,i,1); change(st,i+1,2); ADD; } } else if (p==0&&q!=0) { if (map[u][i+1]==true) ADD; if (map[u+1][i]==true) { change(st,i,q); change(st,i+1,0); ADD; } } else if (p!=0&&q==0) { if (map[u+1][i]==true) ADD; if (map[u][i+1]==true) { change(st,i,0); change(st,i+1,p); ADD; } } else if (p==1&&q==2) { if (u==xx&&i==yy) ans+=sum; } else if (p==2&&q==1) { change(st,i,0); change(st,i+1,0); ADD; } else if (p==1&&q==1) { int top=1; for (int pos=i+2;pos<=m+1;pos++) { int temp=get(st,pos); if (temp==1) top++; if (temp==2) top--; if (top==0) { change(st,i,0); change(st,i+1,0); change(st,pos,1); ADD; break; } } } else if (p==2&&q==2) { int top=1; for (int pos=i-1;pos>0;pos--) { int temp=get(st,pos); if (temp==2) top++; if (temp==1) top--; if (top==0) { change(st,i,0); change(st,i+1,0); change(st,pos,2); ADD; break; } } } } } for (int i=1;i<=num[now];i++) b[now][i]<<=2; }}int main(){ memset(map,false,sizeof(map)); scanf("%d%d",&n,&m); for (int u=1;u<=n;u++) { char ss[15]; scanf("%s",ss+1); for (int i=1;i<=m;i++) if (ss[i]=='.') {xx=u;yy=i;map[u][i]=true;} } if (xx==-1) {printf("0");return 0;} solve(); printf("%lld\n",ans); return 0;}
阅读全文
0 0
- 【caioj】1489: 基于连通性状态压缩的动态规划问题:Formula 1 Ural1519
- [caioj]1489: 基于连通性状态压缩的动态规划问题:Formula 1
- [caioj]1490: 基于连通性状态压缩的动态规划问题:Eat the Trees
- [caioj]1491: 基于连通性状态压缩的动态规划问题:Tony's Tour
- [caioj]1492: 基于连通性状态压缩的动态规划问题:Pipes
- [caioj]1491: 基于连通性状态压缩的动态规划问题:Tony's Tour
- [caioj]1493: 基于连通性状态压缩的动态规划问题:Plan
- [caioj]1493: 基于连通性状态压缩的动态规划问题:Plan
- Ural 1519 Formula 1 基于连通性的状态压缩动态规划
- 基于连通性状态压缩的动态规划问题
- 【连通性状态压缩DP】URAL1519
- 动态规划专题:算法合集之《基于连通性状态压缩动态规划问题》
- 男人8题之Tony's TourPKU1739基于连通性状态压缩的动态规划
- 基于连通性状态压缩的动态规划--【插头DP】模板超级详细解释
- ural1519 Formula 1
- ural1519 Formula 1
- POJ1739 基于连通性的状态压缩dp
- 基于连通性的状态压缩DP
- 自己写的 傻瓜 选择排序
- C++Primer Plus(第六版) 第十三章 第二题
- HDU-2017"百度之星"程序设计大赛-初赛(B)-1005-度度熊的交易计划
- java.lang.Exception: Port 8083 already in use.
- 水晶头接法
- 【caioj】1489: 基于连通性状态压缩的动态规划问题:Formula 1 Ural1519
- Hadoop 运行模式的设置
- java 转换流
- HDU_6097 Mindis 【几何】
- 二维数组与指针
- CTDB代码流程简要梳理
- 心情
- 各种激活函数的比较
- js手机左右滑动