Atcoder Regular 058 E - 和風いろはちゃん / Iroha and Haiku - 状压

题目大意:问有多少长度为N的数列{aN},满足每个数字权值在[1,10]中,并且不存在1<=x

#include
#include
#include
#define lint long long
#define LOG 17
#define maxK 10
#define V 1<
#define N 42
#define mod 1000000007
using namespace std;
inline int updv(int x,int p) { return x|(1<<(p-1)); }
int dp[N][V],can[V];
int fast_pow(int x,int k)
{
    int ans=1;
    while(k)
    {
        if(k&1) ans=(lint)ans*x%mod;
        x=(lint)x*x%mod,k>>=1;
    }
    return ans;
}
int show(int x)
{
    for(int i=1;i<=LOG;i++)
        printf("%d",(x&(1<<(i-1)))>>(i-1));
    cout<return 0;
}
int main()
{
    int n,x,y,z;scanf("%d%d%d%d",&n,&x,&y,&z);
    int all=(1<1,v=0,ans=0;dp[0][0]=1;
    v=updv(v,x+y+z),v=updv(v,y+z),v=updv(v,z);
    for(int i=0;i<=all;i++) can[i]=((i&v)!=v);
    for(int i=0,x;ifor(int j=0;j<=all;j++)
            if(can[j]&&(x=dp[i][j]))
                for(int k=1;k<=maxK;k++)
                    (dp[i+1][all&updv(j<x)%=mod;
    for(int i=1;i<=all;i++)
        if(can[i]) (ans+=dp[n][i])%=mod;
    printf("%d\n",(fast_pow(10,n)-ans+mod)%mod);
    return 0;
}

你可能感兴趣的:(AtCoder,状态压缩,DP动态规划)