HDU 1693 Eat the Trees 插头DP

HDU 1693 Eat the Trees 插头DP

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1693

意甲冠军:给定一个r*c的地,(r,c<=11),当中有的土地上种上了树,有些没有种上树。仅仅能在种上树的地上走,通过走若干个回路,来走遍全部种树的土地。问有多少种走法。

思路:不管怎样还是要先提供一个链接:http://wenku.baidu.com/view/4fe4ac659b6648d7c1c74633.html,是国家队论文。里面对于要提及的概念解说的十分清楚。

dp的过程是从左上角的点到右下角的点进行状态压缩dp。dp[i][j][k]表示第i行第j列时。轮廓线上从左到右是否存在插头的二进制状态k(0表示轮廓线上不存在插头,1表示轮廓线上存在插头)。

每行第零个状态是由右上角的状态第c个状态得到,详细过程是dp[i][0][j<<1]=dp[i-1][c][j]; 这是由于轮廓线从每行的第最后一种状态变成了每行的第一种状态(画画就明确了)。

状态转移也是依据插头的相应情况来写的,是由当前格子的下方轮廓线和右側轮廓线上是否存在插头来决定。

假设下方和右側都存在插头,那么左側和上方就都不能存在插头,所以状态时由上一个状态中相应两位都为0的情况得到。

假设下方和右側都不存在插头,那么左側和上方就都必定存在插头,所以状态时由上一个状态中相应两位都为1的情况得到。

假设下方存在插头,右側不存在插头。或者是右側存在插头,下方不存在插头,那么就可能存在上方存在插头或者是左側存在插头两种情况,分别寻找相应状态加上就可以。

P.S.果然原来插头DP的名字是基于连通性状态压缩的动态规划,本质还是状压…

代码:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <ctype.h>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#define eps 1e-8
#define INF 0x7fffffff
#define maxn 13
#define PI acos(-1.0)
#define seed 31//131,1313
//#define LOCAL
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
LL dp [maxn][maxn][1<<maxn] ;
int M [maxn][maxn] ;
int row,col;
LL solve(int r,int c)
{
    int tot=1<<(c+1);
    memset(dp,0,sizeof(dp));
    dp[0][c][0]=1;
    for(int i=1; i<=r; i++)
    {
        for(int j=0; j<tot; j++)
            dp[i][0][j<<1]=dp[i-1][c][j];
        for(int j=1; j<=c; j++)
        {
            int st1=(1<<j),st2=(1<<(j-1));
            for(int k=0; k<tot; k++)
            {
                if(M[i][j]==1)
                {
                    if((k&st1)==0&&(k&st2)==0)
                        dp[i][j][k]=dp[i][j-1][k+st1+st2];
                    else if((k&st1)!=0&&(k&st2)!=0)
                        dp[i][j][k]=dp[i][j-1][k-st1-st2];
//                    else
//                    {
//                        dp[i][j][k]+=dp[i][j-1][k];
//                        dp[i][j][k]+=dp[i][j-1][k^st1^st2];
//                    }//与下述状态转移等效。且更优美
                    else if((k&st1)==0&&(k&st2)!=0)
                    {
                        dp[i][j][k]+=dp[i][j-1][k-st2+st1];
                        dp[i][j][k]+=dp[i][j-1][k];
                    }
                    else
                    {
                        dp[i][j][k]+=dp[i][j-1][k-st1+st2];
                        dp[i][j][k]+=dp[i][j-1][k];
                    }
                }
                else if((k&st1)==0&&(k&st2)==0)
                    dp[i][j][k]=dp[i][j-1][k];
            }
        }
    }
    return dp[r][c][0];
}
int main()
{
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
#endif
    int T;
    scanf("%d",&T);
    for(int ii=1;ii<=T;ii++)
    {
        scanf("%d%d",&row,&col);
        for(int i=1; i<=row; i++)
            for(int j=1; j<=col; j++)
                scanf("%d",&M[i][j]);
        printf("Case %d: There are %I64d ways to eat the trees.\n",ii,solve(row,col));
    }
    return 0;
}

版权声明:本文博客原创文章。博客,未经同意,不得转载。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/117382.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 3. CMake 系列 – 分模块编译&安装项目

    3. CMake 系列 – 分模块编译&安装项目

    2021年11月22日
    41
  • Partitioner分区过程分析

    Partitioner分区过程分析

    2022年1月9日
    47
  • 我是如何自学 Python 的

    我是如何自学 Python 的我是如何自学Python的

    2022年8月5日
    4
  • android之Widget开发详解实例一「建议收藏」

    Android Widget开发案例实现是本文要介绍的内容,主要是来了解并学习Android Widget开发应用,今天我们要写一下Android Widget的开发,由于快点凌晨,我就不说的太具体了,同志们就模仿吧!首先看一下效果图: 下面是Demo的详细步骤:一、新建一个Android工程命名为:WidgetDemo.二、准备素材,一个是Widget的图标,一个是W

    2022年3月10日
    43
  • 迪奥布兰度正在挑战fgo 小说_god eater resurrection

    迪奥布兰度正在挑战fgo 小说_god eater resurrectiongodis之aof持久化文章目录godis之aof持久化基本说明文件写入加载文件文件重写数据转化为redis命令外部调用基本说明在godis中,只有aof持久化,而没有rdb持久化。aof持久化分为三个基本的模块:将命令持久化到aof文件将aof文件的命令加载到内存aof文件重写文件写入handlerAof函数的作用是将命令持久化到aof文件中。它监听着aof通道并写入到aof文件,在初始化handler的时候,就开启一个子goroutine来执行这个函数。//监听aof通

    2022年10月8日
    0
  • Linux——vi命令详解[通俗易懂]

    Linux——vi命令详解[通俗易懂]vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器,这里只是简单地介绍一下它的用法和一小部分指令。由于对Unix及Linux系统的任何版本,vi编辑器是完全相同的,因此您可以在其他任何介绍vi的地方进一步了解它。Vi也是Linux中最基本的文本编辑器,学会它后,您将在Linux的世界里畅行无阻。

    2022年6月9日
    85

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号