码迷,mamicode.com
首页 > 其他好文 > 详细

【HDU1693】Eat the Trees(插头dp)

时间:2018-12-09 18:48:08      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:分配   amp   size   return   www   tin   HERE   hdu   cas   

【HDU1693】Eat the Trees(插头dp)

题面

HDU
Vjudge
大概就是网格图上有些点不能走,现在要找到若干条不相交的哈密顿回路使得所有格子都恰好被走过一遍。

题解

这题的弱化版本吧。。。
因为可以任意分配哈密顿回路的数量,因此根本不需要再考虑插头的配对问题了,那么直接分情况转移就好啦。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define MAX 13
inline int read()
{
    int x=0;bool t=false;char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=true,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return t?-x:x;
}
int bin[MAX];
ll f[MAX][MAX][1<<12];
int n,m;
int g[MAX][MAX];
int main()
{
    int T=read();
    bin[0]=1;for(int i=1;i<13;++i)bin[i]=bin[i-1]<<1;
    for(int TT=1;TT<=T;++TT)
    {
        n=read();m=read();memset(g,0,sizeof(g));memset(f,0,sizeof(f));
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j)
                g[i][j]=read();
        f[0][m][0]=1;int S=1<<(m+1);
        for(int i=1;i<=n;++i)
        {
            for(int k=0;k<S>>1;++k)f[i][0][k<<1]=f[i-1][m][k];
            for(int j=1;j<=m;++j)
                for(int k=0;k<S;++k)
                {
                    int left=(k>>(j-1))&1,up=(k>>j)&1;
                    if(!g[i][j])
                    {
                        if(!left&&!up)f[i][j][k]+=f[i][j-1][k];
                        continue;
                    }
                    if(!left&&!up)
                        if(g[i+1][j]&&g[i][j+1])f[i][j][k+bin[j-1]+bin[j]]+=f[i][j-1][k];
                    if(!left&&up)
                    {
                        if(g[i+1][j])f[i][j][k+bin[j-1]-bin[j]]+=f[i][j-1][k];
                        if(g[i][j+1])f[i][j][k]+=f[i][j-1][k];
                    }
                    if(left&&!up)
                    {
                        if(g[i+1][j])f[i][j][k]+=f[i][j-1][k];
                        if(g[i][j+1])f[i][j][k-bin[j-1]+bin[j]]+=f[i][j-1][k];
                    }
                    if(left&&up)f[i][j][k-bin[j-1]-bin[j]]+=f[i][j-1][k];
                }
        }
        printf("Case %d: There are %lld ways to eat the trees.\n",TT,f[n][m][0]);
    }
}

【HDU1693】Eat the Trees(插头dp)

标签:分配   amp   size   return   www   tin   HERE   hdu   cas   

原文地址:https://www.cnblogs.com/cjyyb/p/10092309.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!