P2327 [SCOI2005]扫雷

题目描述

输入输出格式

输入格式:

第一行为N,第二行有N个数,依次为第二列的格子中的数。(1<= N <= 10000)

输出格式:

一个数,即第一列中雷的摆放方案数。

输入输出样例

输入样例#1: 复制
2
1  1
输出样例#1: 复制
2


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define inf 2147483647
const ll INF = 0x3f3f3f3f3f3f3f3fll;
#define ri register int
template <class T> inline T min(T a, T b, T c)
{
    return min(min(a, b), c);
}
template <class T> inline T max(T a, T b, T c)
{
    return max(max(a, b), c);
}
template <class T> inline T min(T a, T b, T c, T d)
{
    return min(min(a, b), min(c, d));
}
template <class T> inline T max(T a, T b, T c, T d)
{
    return max(max(a, b), max(c, d));
}
#define pi acos(-1)
#define me(x, y) memset(x, y, sizeof(x));
#define For(i, a, b) for (int i = a; i <= b; i++)
#define FFor(i, a, b) for (int i = a; i >= b; i--)
#define mp make_pair
#define pb push_back
const int maxn = 100005;
#define mod 100003
const int N=100005;

// name*******************************
int f[N][20];
int n;
int num[100005];
int ans=0;
// function******************************
int counter(int x)
{
    int res=0;
    while(x)
    {
        x&=(x-1);
        res++;
    }
    return res;
}


//***************************************
int main()
{
//freopen("test.txt", "r", stdin);
    cin>>n;
    For(i,1,n)
    cin>>num[i];
    f[1][0]=1;
    f[1][4]=1;
    For(i,2,n)
    {
        For(j,0,7)
        {
            if(counter(j)!=num[i-1]||counter(j>>1)>num[i])continue;
            f[i][j]+=f[i-1][(j<<1)%8]+f[i-1][((j<<1)%8)|1];
        }
    }

    For(i,0,7)
    {
        if(counter(i)==num[n-1]&&counter(i>>1)==num[n])
            ans+=f[n][i];
    }
    cout<<ans;

    return 0;
}
原文地址:https://www.cnblogs.com/planche/p/8665726.html