zoukankan      html  css  js  c++  java
  • 一本通1592【例 1】国王

    1592:【例 1】国王

    时间限制: 500 ms         内存限制: 65536 KB

    【题目描述】

    原题来自:SGU 223

    在 n×n 的棋盘上放 k 个国王,国王可攻击相邻的 8 个格子,求使它们无法互相攻击的方案总数。

    【输入】

    只有一行,包含两个整数 n 和 k。

    【输出】

    每组数据一行为方案总数,若不能够放置则输出 0。

    【输入样例】

    3 2

    【输出样例】

    16

    【提示】

    样例输入 2

    4 4

    样例输出 2 

    79

    数据范围与提示:

    对于全部数据,1≤n≤10,0≤k≤n2

    sol:我自己的做法很劣,几乎是所有提交里最慢的,my:预处理暴力枚举两条边上的状态看看是否可转移,然后n*m*2n*2n,这居然过了,我也是醉了

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    inline ll read()
    {
        ll s=0;
        bool f=0;
        char ch=' ';
        while(!isdigit(ch))
        {
            f|=(ch=='-');
            ch=getchar();
        }
        while(isdigit(ch))
        {
            s=(s<<3)+(s<<1)+(ch^48);
            ch=getchar();
        }
        return (f)?(-s):(s);
    }
    #define R(x) x=read()
    inline void write(ll x)
    {
        if(x<0)
        {
            putchar('-');
            x=-x;
        }
        if(x<10)
        {
            putchar(x+'0');
            return;
        }
        write(x/10);
        putchar((x%10)+'0');
        return;
    }
    inline void writeln(ll x)
    {
        write(x);
        putchar('
    ');
        return;
    }
    #define W(x) write(x),putchar(' ')
    #define Wl(x) writeln(x)
    const int N=15;
    int n,m,Ges[(1<<10)+5];
    ll dp[N][N*N][(1<<10)+5];
    bool Can[(1<<10)+5][(1<<10)+5],Jud[(1<<10)+5];
    int main()
    {
        int i,j,k,ii,jj;
        R(n); R(m);
        for(i=0;i<(1<<n);i++)
        {
            bool bo=1;
            for(j=2;j<=n&&bo;j++) if((i&(1<<(j-2)))&&(i&(1<<(j-1)))) bo=0;
            Jud[i]=bo;
        }
        for(i=0;i<(1<<n);i++) if(Jud[i])
        {
            for(j=0;j<(1<<n);j++) if(Jud[j])
            {
                bool bo=1;
                if(i&(1<<(1-1))) if((j&(1<<(1-1)))||(j&(1<<(2-1)))) bo=0;
                for(k=2;k<n&&bo;k++) if(i&(1<<(k-1)))
                {
                    if((j&(1<<(k-2)))||(j&(1<<(k-1)))||(j&(1<<(k)))) bo=0;
                }
                if(i&(1<<(n-1))) if((j&(1<<(n-2)))||(j&(1<<(n-1)))) bo=0;
                if(bo)    Can[i][j]=1;
            }
        }
        for(i=0;i<(1<<n);i++)
        {
            Ges[i]=0;
            for(j=1;j<=n;j++) if(i&(1<<(j-1))) Ges[i]++;
            dp[1][Ges[i]][i]=1;
        }
        for(i=2;i<=n;i++)
        {
            for(j=0;j<=m;j++)
            {
                for(ii=0;ii<(1<<n);ii++) if(dp[i-1][j][ii]&&Jud[ii])
                {
                    for(jj=0;jj<(1<<n);jj++) if(Can[ii][jj]&&j+Ges[jj]<=m&&Jud[jj])
                    {
                        dp[i][j+Ges[jj]][jj]+=dp[i-1][j][ii];
                    }
                }
            }
        }
        ll ans=0;
        for(i=0;i<(1<<n);i++) ans+=dp[n][m][i];
        Wl(ans);
        return 0;
    }
    /*
    input
    3 2
    output
    16
    
    input
    4 4
    output
    79
    */
    View Code

     肯定有更优的解法,(同种做法不可能差70ms),但我不知道qaq

  • 相关阅读:
    js截取字符串区分汉字字母代码
    List 去处自定义重复对象方法
    63. Unique Paths II
    62. Unique Paths
    388. Longest Absolute File Path
    41. First Missing Positive
    140. Word Break II
    139. Word Break
    239. Sliding Window Maximum
    5. Longest Palindromic Substring
  • 原文地址:https://www.cnblogs.com/gaojunonly1/p/10363376.html
Copyright © 2011-2022 走看看