• uvalive 6323 状态压缩DP


    思路:dp[i][j][x]表示状态 i 以 j 为结束 得分为 x 的方案数。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    using namespace std;
    int dp[5000][13][40],g[5][5],d[13][13],n,l,ans;
    bool vi[13],ntou[13];
    struct Point{
        int x,y;
    }p[13];
    bool OK(int a,int b)
    {
        int x1,y1,x2,y2,i;
        x1=p[a].x,y1=p[a].y;
        x2=p[b].x,y2=p[b].y;
        if(x1==x2){
            if(y1>y2)
                swap(y1,y2);
            for(i=y1+1;i<y2;i++) if(!vi[g[x1][i]]||ntou[g[x1][i]])
            return false;
        }
        if(y1==y2){
            if(x1>x2)
                swap(x1,x2);
            for(i=x1+1;i<x2;i++) if(!vi[g[i][y1]]||ntou[g[i][y1]])
                return false;
        }
        if(abs(x1-x2)==2&&abs(y1-y2)==2){
            int x=(x1+x2)/2;
            int y=(y1+y2)/2;
            if(!vi[g[x][y]]||ntou[g[x][y]])
                return false;
        }
        return true;
    }
    void init()
    {
        int i,j,cnt=0;
        for(i=1;i<=3;i++){
            for(j=1;j<=4;j++){
                g[i][j]=++cnt;
                p[cnt].x=i,p[cnt].y=j;
            }
        }
        for(i=1;i<=12;i++){
            for(j=1;j<=12;j++){
                d[i][j]=abs(p[i].x-p[j].x)+abs(p[i].y-p[j].y);
            }
        }
    }
    void solve()
    {
        int i,j,k,r;
        ans=0;
        int N=(1<<12)-1;
        for(i=0;i<12;i++)
            dp[1<<i][i+1][0]=1;
        for(i=1;i<=N;i++){
            memset(vi,0,sizeof(vi));
            for(k=0;k<12;k++) if(((1<<k)&i)) vi[k+1]=1;
            for(j=0;j<12;j++) if((((1<<j)&i))&&!ntou[j+1]){
                for(k=0;k<12;k++) if(((1<<k)&i)==0&&!ntou[k+1]&&OK(j+1,k+1)){
                    //cout<<p[j+1].x<<" "<<p[j+1].y<<" "<<p[k+1].x<<" "<<p[k+1].y<<endl;
                    for(r=0;r<=40;r++){
                        dp[i|(1<<k)][k+1][r+d[j+1][k+1]]+=dp[i][j+1][r];
                    }
                }
            }
        }
        for(i=1;i<=N;i++){
            for(j=1;j<=12;j++){
                ans+=dp[i][j][l];
            }
        }
    }
    int main()
    {
        int i,j,t,x,y;
        init();
        scanf("%d",&t);
        while(t--){
            memset(dp,0,sizeof(dp));
            memset(vi,0,sizeof(vi));
            memset(ntou,0,sizeof(ntou));
            scanf("%d%d",&l,&n);
            for(i=1;i<=n;i++){
                scanf("%d%d",&x,&y);
                ntou[g[x][y]]=1;
            }
            if(l>=40){
                printf("BAD MEMORY
    ");
                continue;
            }
            solve();
            if(ans)
                printf("%d
    ",ans);
            else
                printf("BAD MEMORY
    ");
        }
        return 0;
    }
  • 相关阅读:
    「CF1380G」 Circular Dungeon
    「CF1208G」 Polygons
    P4827「国家集训队」 Crash 的文明世界
    「CF85E」 Guard Towers
    「BZOJ 2956」模积和
    「HEOI2016/TJOI2016」排序
    CF277E Binary Tree on Plane
    「SDOI2016」数字配对
    HNOI2020「Elegy」
    CSP-S2019「Symphony」
  • 原文地址:https://www.cnblogs.com/wangfang20/p/3362625.html
Copyright © 2020-2023  润新知