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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • matlab在极坐标中绘图y=sin(6x)_极坐标中θ范围怎么求

    matlab在极坐标中绘图y=sin(6x)_极坐标中θ范围怎么求在极坐标中绘图TryThisExampleTryThisExampleTryThisExampleTryThisExampleTryThisExampleTryThi

    2022年8月5日
    4
  • dos清除windows密码命令_哪些文件会被dos病毒感染

    dos清除windows密码命令_哪些文件会被dos病毒感染 今天,朋友叫我帮看看他的电脑,说是中了个比较NB的病毒,我颇感兴趣!因为好久没有遇到有挑战性的病毒了!今天又可以练练手了^_^打开他的电脑,并没有发现什么特别具有破坏力的现象。exe、com、src等等文件都没有被感染,GHOST备份文件也还在。仔细查看系统,归纳起来,中毒后主要呈现如下症状:1.杀毒软件被中止和禁止重新启用,系统垃圾清除类软件被禁止启用。中毒后注销重新进入系

    2022年10月3日
    0
  • Linux进程和计划任务管理

    Linux进程和计划任务管理

    2021年9月6日
    56
  • 下列选项中不符合python语言变量命名规则的是_下列选项中不符合Python语言变量命名规则的是??????????????????????????????????( )。…

    下列选项中不符合python语言变量命名规则的是_下列选项中不符合Python语言变量命名规则的是??????????????????????????????????( )。…下列选项中不符合Python语言变量命名规则的是??????????????????????????????????()。答:3_1下列基金的收益与股票市场平均收益率最接近的是()。答:股票基金自由锻基本工序有、、答:镦粗拔长冲孔中国第一颗的爆炸时间是答:1967年废品净损失应由()。答:同种合格产品成本负担下列各进制的整数中,值最小的是()答:二进制数11春风雨:理性…

    2022年5月28日
    40
  • linux查看文件权限修改记录_文件修改记录

    linux查看文件权限修改记录_文件修改记录1、从文件类型上分可分为三种,   用ls-l查询,以“一”开头的是文件,以字母“d”开头的是目录(俗称文件夹),以字母“l”开头的是连接。 2、剩下的9个分别三个为一组每一组都有四种符号组成分别是“r”,“w”,“x”,“-”。    r(read):代表读的权限    w(write):代表写的权限    x(execuite):

    2022年9月11日
    1
  • NetworkManager详解

    NetworkManager详解直接继承自 MonoBehaviour, 还有就是被设计成了单例 singletonNetworkManager网络管理器是一个方便的HLAPI类,用于管理网络系统。       对于简单的网络应用NetworkManager网络管理器可以使用HLAPI控制。它提供了简单的方法来 启动和停止 客户端和服务器,以及管理场景,而且具有虚拟函数,用户代码可以使

    2022年10月5日
    4

发表回复

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

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