• 【HDU1693】Eat the Trees-插头DP


    测试地址:Eat the Trees

    题目大意:一个N*M的矩形场地,有一些格子不能走,要求走若干条回路使得走过每个格子一次且仅一次,求方案数。

    做法:一看到棋盘类型的题目和很小的数据范围就想到插头DP。因为题目中要求若干条回路,所以轮廓线状态定义直接和骨牌覆盖问题一样,插头为1表示这个位置需要一个格子来承接,插头为0表示不需要。设f[i][j][state]为递推到第i行第j列的格子,轮廓线状态为state的方案数,逐格递推,枚举轮廓线状态,并找出第j和第j+1位(从左到右),称作关键位,判断:如果当前格子不能走,那么仅当两个关键位都为0时才更新状态,此时f[i][j][state]=f[i][j-1][state],否则f[i][j][state]=0。如果当前格子能走,按照关键位分成3种情况:两个关键位都为0,两个关键位都为1或者其中一个关键位为0,另一个关键位为1,分情况状态转移即可。和一般的插头DP问题一样,要注意递推到一行最后一个格子时轮廓线状态的转移。

    我傻逼的地方:轮廓线状态是m+1位的,所以数组要开到2^(m+1)那么多,而不是2^m......结果我交上去竟然提示TLE而不是RE,很迷......

    以下是本人代码:

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    using namespace std;
    int n,m,T,w[20][20],now,past;
    ll f[2][5010];
    
    int main()
    {
      scanf("%d",&T);
      for(int t=1;t<=T;t++)
      {
        memset(f,0,sizeof(f));
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    	  for(int j=1;j<=m;j++)
    	    scanf("%d",&w[i][j]);
    	f[0][0]=1;
    	now=1,past=0;
    	for(int i=1;i<=n;i++)
    	  for(int j=1;j<=m;j++)
    	  {
    	    for(int k=0;k<(1<<(m+1));k++)
    		{
    		  int bit1=k&(1<<(j-1)),bit2=k&(1<<j);
    		  if (!bit1&&!bit2)
    		  {
    		    if (!w[i][j]) f[now][k]=f[past][k];
    			else f[now][k]=f[past][k+(1<<(j-1))+(1<<j)];
    		  }
    		  else if (!w[i][j]) {f[now][k]=0;continue;}
    		  else if (bit1&&bit2) f[now][k]=f[past][k-(1<<(j-1))-(1<<j)];
    		  else
    		  {
    		    if (bit1) f[now][k]=f[past][k]+f[past][k-(1<<(j-1))+(1<<j)];
    			else f[now][k]=f[past][k]+f[past][k-(1<<j)+(1<<(j-1))];
    		  }
    		}
    		if (j==m)
    		{
    		  for(int k=(1<<(m+1));k>=0;k--)
    		  {
    		    if (k%2) f[now][k]=0;
    			else f[now][k]=f[now][k>>1];
    		  }
    		}
    		swap(now,past);
    	  }
    	printf("Case %d: There are %lld ways to eat the trees.
    ",t,f[past][0]);
      }
      
      return 0;
    }
    


  • 相关阅读:
    crontab
    待重写
    待重写
    多套开发资源使用情况
    待重写
    待重写
    待重写
    docker安装es
    docker run启动时目录映射研究
    rabbitmq第二篇:使用插件实现延迟功能
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793781.html
Copyright © 2020-2023  润新知