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

hdu1693 插头dp

时间:2015-11-07 17:41:17      阅读:214      评论:0      收藏:0      [点我收藏+]

标签:

题意:给了一个矩阵图,要求使用回路把图中的树全部吃掉的方案树,没有树的点不能走,吃完了这个点也就没有了,走到哪吃到哪

用插头dp搞

技术分享
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <string.h>
using namespace std;
typedef long long LL;
int G[11][11];
int nrows,ncols;
struct State
{
    int up[11];
    int left;
    int encode()const
    {
        int key=left;
        for(int i=0; i<ncols; i++)key=key*2+up[i];
        return key;
    }
    bool next(int row,int col, int U, int D, int L, int R,State &T)const
    {
        if(row==nrows-1 && D!=0 )return false;
        if(col==ncols-1 && R!=0 )return false;
        int must_left = (col>0&&left!=0);
        int must_up = (row>0 && up[col]!=0);
        if( ( must_left!=0 && L==0) || (must_left==0 && L!=0) )return false ;
        if( ( must_up !=0 && U== 0) || (must_up ==0 && U!=0 )) return false;
        for(int i=0; i<ncols; i++)T.up[i]=up[i];
        T.up[col]=D;
        T.left=R;
        return true;
    }
};
LL memo[11][11][1<<13];
LL rec(int row,int col,const State &S)
{
    if(col == ncols ){ col=0; row++ ;}
    if(row == nrows) return 1;
    int key=S.encode();
    LL &res=memo[row][col][key];
    if(res>=0)return res;
    res=0;
    State T;
    if(G[row][col])
    {
       if(S.next(row,col,1,1,0,0,T))
        res+=rec(row,col+1,T);
       if(S.next(row,col,1,0,1,0,T))
        res+=rec(row,col+1,T);
       if(S.next(row,col,1,0,0,1,T))
        res+=rec(row,col+1,T);
       if(S.next(row,col,0,1,1,0,T))
        res+=rec(row,col+1,T);
       if(S.next(row,col,0,1,0,1,T))
        res+=rec(row,col+1,T);
       if(S.next(row,col,0,0,1,1,T))
        res+=rec(row,col+1,T);
    }else
    {
        if(S.next(row,col,0,0,0,0,T))
         res+=rec(row,col+1,T);
    }
    return res;
}
int main()
{
    int cas;
    scanf("%d",&cas);
    for(int cc=1; cc<=cas; cc++)
    {
        scanf("%d%d",&nrows,&ncols);
        for(int i=0; i<nrows; i++)
            for(int j=0; j<ncols ;j++)
            scanf("%d",&G[i][j]);
        State S;
        memset(&S,0,sizeof(S));
        memset(memo,-1,sizeof(memo));
        LL ans=rec(0,0,S);
        printf("Case %d: There are %I64d ways to eat the trees.\n",cc,ans);
    }
    return 0;
}
View Code

 

hdu1693 插头dp

标签:

原文地址:http://www.cnblogs.com/Opaser/p/4945710.html

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