萌新初学DP,求助
查看原帖
萌新初学DP,求助
239192
淸梣ling楼主2021/10/29 23:02

代码没有找到bug,希望来个大佬帮忙找找,谢谢了!!!

思想跟一般的差不多,只不过是第一个位置存的是竖向的关键点

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

const int LIM = 300005;
const int HASH = 299989;


int n,m;
int endx,endy;
bool a[20][20];

int h[LIM],nextH[LIM];

int f[2][LIM];
int ans;

int sat[2][LIM],sum[2],now;


void add(int cnt, int num)
{
    int hash=cnt%HASH+1; //取hash值
    
    printf("add %d\n",cnt);

    // 开链避免哈希冲突
    for(int i=h[hash];i;i=nextH[i])
    if(sat[now][i]==cnt)
    {
        f[now][i]+=num; //方案累计
        return;
    }

    //新状态,记录
    ++sum[now];
    nextH[sum[now]]=h[hash];
    h[hash]=sum[now];
    sat[now][sum[now]]=cnt;
    f[now][sum[now]]=num;
}
void work()
{
    int i,j,k;

    sum[now]=1;
    f[now][1]=1;

    for(i=1;i<=n;i++)
    for(j=1;j<=m;j++)
    {
        int old=now; now=!now; //数组滚动
        sum[now]=0;
        memset(h,0,sizeof(h));

        for(k=1;k<=sum[old];k++)
        {
            int cnt=sat[old][k]; //状态
            int b1=cnt&3; //纵向关键点
            int b2=(cnt>>j*2)&3; //横向关键点
            int num=f[old][k]; //k状态的方案个数

            if(!a[i][j]) //当前位置是障碍
            {
                if(!b1&&!b2)
                add(cnt,num);
            }
            else if(!b1&&!b2)
            {
                if(a[i+1][j]&&a[i][j+1])
                add(cnt+(1<<j*2)+2,num);
            }
            else if(!b1&&b2)
            {
                if(a[i][j+1]) add(cnt+b2-(b2<<j*2),num);
                if(a[i+1][j]) add(cnt,num);
            }
            else if(b1&&!b2)
            {
                if(a[i][j+1]) add(cnt,num);
                if(a[i+1][j]) add(cnt-b1+(b1<<j*2),num);
            }
            else if(b1==1&&b2==1)
            {
                int kl=1;
                for(int t=j+1;t<=m;t++)
                {
                    if((cnt>>t*2)&3==1) ++kl;
                    if((cnt>>t*2)&3==2) --kl;
                    if(kl==0)
                    {
                        add(cnt-b1-(b2<<j*2)-(1<<t*2),num);
                        break;
                    }
                }
            }
            else if(b1==2&&b2==2)
            {
                int kl=1;
                for(int t=j-1;t>=1;t--)
                {
                    if((cnt>>t*2)&3==1) --kl;
                    if((cnt>>t*2)&3==2) ++kl;
                    if(kl==0)
                    {
                        add(cnt-b1-(b2<<j*2)+(1<<t*2),num);
                        break;
                    }
                }
            }
            else if(b1==2&&b2==1)
            add(cnt-b1-(b2<<j*2),num);
            else if(b1==1&&b2==2)
            {
                if(i==endx&&j==endy)
                ans+=num;
            }
        }
    }

    cout<<ans;
}
int main()
{
    int i,j;
    char c;

    cin>>n>>m;
    for(i=1;i<=n;i++)
    for(j=1;j<=m;j++)
    {
        while((c=getchar())&&c!='.'&&c!='*');
        if(c=='.')
        {
            a[i][j]=1;
            endx=i; endy=j;
        }
    }

    work();
    return 0;
}
2021/10/29 23:02
加载中...