zoukankan      html  css  js  c++  java
  • P5074 Eat the Trees

    思路

    同样是插头DP,但是这题因为可以形成多个回路,所以左右括号是没有区别的,只需要01就可以表示了
    注意if的嵌套关系
    注意全零矩阵也要输出1

    代码

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define int long long
    using namespace std;
    const int HASHsize = 400000;
    int mat[20][20],n,m,T,pos[40];
    int cnt[2],now,last,ans,endx,endy,fir[HASHsize+10],nxt[HASHsize+10],val[2][HASHsize+10],times[2][HASHsize+10];
    void init(void){
        memset(mat,0,sizeof(mat));
        memset(cnt,0,sizeof(cnt));
        now=0,last=0,ans=0,endx=0,endy=0;
        memset(fir,0,sizeof(fir));
        memset(nxt,0,sizeof(nxt));
        memset(val,0,sizeof(val));
        memset(times,0,sizeof(times));
    }
    void insert(int c,int num){
        int t=c%HASHsize;
        for(int i=fir[t];i;i=nxt[i]){
            if(val[now][i]==c){
                times[now][i]+=num;
                return;
            }
        }
        ++cnt[now];
        val[now][cnt[now]]=c;
        times[now][cnt[now]]=num;
        nxt[cnt[now]]=fir[t];
        fir[t]=cnt[now];
    }
    void print(int x){
        for(int i=0;i<m+1;i++)
            printf("%lld",(x>>i)&1);
        printf("
    ");
    }
    void dp(void){
        now=0;
        insert(0,1);
        for(int i=1;i<=n;i++){
            for(int k=1;k<=cnt[now];k++)
                val[now][k]<<=1;
            for(int j=1;j<=m;j++){
                last=now;
                now^=1;
                cnt[now]=0;
                memset(fir,0,sizeof(fir));
                memset(nxt,0,sizeof(nxt));
                // printf("i=%lld j=%lld
    ",i,j);
                for(int k=1;k<=cnt[last];k++){
                    int state=val[last][k],num=times[last][k],plugL=(state>>(j-1))&1,plugU=(state>>(j))&1;
                    // printf("num=%lld
    ",num);
                    // print(state);
                    // printf("plugL=%lld plugU=%lld
    ",plugL,plugU);
                    if(mat[i][j]){
                        //新建连通分量
                        if((!plugL)&&(!plugU)){
                            if(mat[i+1][j]&&mat[i][j+1])
                                insert(state+(1<<(j-1))+(1<<(j)),num);
                        }
                        //合并联通分量
                        else if(plugL&&plugU){
                            if(i==endx&&j==endy)
                                ans+=num;
                            else
                                insert(state-(1<<(j-1))-(1<<(j)),num);
                        }
                        //延续联通分量
                        else{
                            if(plugL){
                                // printf("!
    ");
                                if(mat[i+1][j])
                                    insert(state,num);
                                if(mat[i][j+1])
                                    insert(state-(1<<(j-1))+(1<<(j)),num);
                            }
                            if(plugU){
                                if(mat[i+1][j])
                                    insert(state-(1<<(j))+(1<<(j-1)),num);
                                if(mat[i][j+1])
                                    insert(state,num);
                            }
                        }
                    }
                    else{
                        if((!plugL)&&(!plugU))
                            insert(state,num);
                    }
                }
            }
        }
    }
    signed main(){
        scanf("%lld",&T);
        pos[0]=1;
        for(int i=1;i<30;i++)
            pos[i]=pos[i-1]<<1;
        while(T--){
            bool isok=true;
            init();
            scanf("%lld %lld",&n,&m);
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++){
                    scanf("%lld",&mat[i][j]);
                    if(mat[i][j]){
                        endx=i;endy=j;
                        isok=false;
                    } 
                }
            // printf("endx=%lld endy=%lld
    ",endx,endy);
            if(!isok){
                dp();
                printf("%lld
    ",ans);
            }
            else{
                printf("1
    ");
            }
        }
        return 0;
    }
    
  • 相关阅读:
    【北邮人论坛帖子备份】【心得】20年公考经验分享
    如何写一封国际会议的交流信?
    花呗广告趣图
    《第九个寡妇》读后感
    沟通的五个层次
    部署多功能模块依赖项目中解决的问题
    maven: can't resolve plugin xxxmaven-xxxx-plugin:x.x
    C++编译报错:need 'typename' before 'std::map<T, S>::iterator' because 'std::map<T, S>' is a dependent scope
    详细js中(function(window,document,undefined))的作用
    201509020-js
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10839614.html
Copyright © 2011-2022 走看看